/* code03e9.c - SysUIAppSwitch handler
   Copyright © 2000 by Mitch Blevins
   Distributed under the GNU GPL.
   Based on LinkHistoryHack by Ben Darnell <bgdarnel@unity.ncsu.edu>
   which was based on...
   Based on SampleHack by Roger Chaplin <foursquaredev@att.net>
*/

#include <Pilot.h>
#include <FeatureMgr.h>

#include "phlegm.h"
#include "phlegmRsc.h"

     
Err MySysAppLaunch(UInt cardNo, LocalID dbID, UInt launchFlags, Word cmd,
                                Ptr cmdPBP, DWord *resultP) {

    DWord temp;
    Err (*oldTrap)(UInt,LocalID,UInt,Word,Ptr,DWord*);
    ULong dbType;
    DWord *ignoredapps;
    DWord dbCreator;
    Word prefssize, numignored;
    JumpRefPref jumpRefs[NUM_ITEMS+1];
    JumpRefPref tempRef;
    Char dbName[dmDBNameLength];
    UInt i, j;

    FtrGet(MYCRID, 0x3e9, &temp);
    oldTrap=(Err(*)(UInt,LocalID,UInt,Word,Ptr,DWord*))temp;

    if (launchFlags&sysAppLaunchFlagNewGlobals) {
        // Find the creatorID, type and name
        MemSet(&tempRef, sizeof(JumpRefPref), 0);
        if (DmDatabaseInfo(cardNo, dbID, dbName, NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL, &dbType, &dbCreator)) goto alldone;
        tempRef.creator = dbCreator;

        // Ignore it if it is not an application
        if (dbType != sysFileTApplication) goto alldone;
        // Ignore the built-in launcher
        if (dbCreator == 'lnch') goto alldone;

        // Fetch the ignored apps
        prefssize = 0;
        if ((PrefGetAppPreferences(MYCRID, IGNOREPREFS, NULL, &prefssize, true)
                       ==noPreferenceFound)||(prefssize==0)) goto doneignoring;
        ignoredapps = MemPtrNew(prefssize);
        if (!ignoredapps) goto doneignoring;
        MemSet(ignoredapps, prefssize, 0);
        if ((PrefGetAppPreferences(MYCRID, IGNOREPREFS, ignoredapps, &prefssize,
                    true)==noPreferenceFound)||(prefssize==0)) {
            MemPtrFree(ignoredapps);
            goto doneignoring;
        }
        // Check if the currently launched app is to be ignored
        numignored = prefssize/sizeof(DWord);
        for (i = 0; i<numignored; i++) {
            if (ignoredapps[i] == dbCreator) {
                MemPtrFree(ignoredapps);
                goto alldone;
            }
        }
        MemPtrFree(ignoredapps);
doneignoring:

        // Get the text width
        tempRef.width = FntCharsWidth(dbName, StrLen(dbName));
 
        // Shuffle the prefs to reflect the new reality
        prefssize = (NUM_ITEMS+1)*sizeof(JumpRefPref);
        MemSet(&(jumpRefs[0]), prefssize, 0);
        if ((PrefGetAppPreferences(MYCRID, REFPREFS, &(jumpRefs[0]), &prefssize,
                        true)==noPreferenceFound)||
                        (prefssize<(NUM_ITEMS+1)*sizeof(JumpRefPref))) {
            MemSet(&(jumpRefs[0]), (NUM_ITEMS+1)*sizeof(JumpRefPref), 0);
        }
        // Find the last cached jumpref
        for (i=0; i<(NUM_ITEMS+1); i++) {
            if(!jumpRefs[i].creator) break;
            if(jumpRefs[i].creator==tempRef.creator) {
                // Already on the list
                MemMove(&tempRef, &(jumpRefs[i]), sizeof(JumpRefPref));
                break;
            }
        }
        // Make sure a favorite is not pushed off the list
        if (i>NUM_ITEMS) {
            i=NUM_ITEMS;
            for (j=i; j>0; j--) {
                if (jumpRefs[j].flags&IS_A_FAV) i=j-1;
                else break;
            }
        }
        // Shuffle up in the list
        for (j=i; j>0; j--) {
            MemMove(&(jumpRefs[j]), &(jumpRefs[j-1]), sizeof(JumpRefPref));
        }
        MemMove(&(jumpRefs[0]), &tempRef, sizeof(JumpRefPref));
        PrefSetAppPreferences(MYCRID, REFPREFS, 0, &(jumpRefs[0]),
                                (NUM_ITEMS+1)*sizeof(JumpRefPref), true);
    }

alldone:
    return oldTrap(cardNo, dbID, launchFlags, cmd, cmdPBP, resultP);
}

