#include <prefs/workbench.h>
#include <workbench/workbench.h>
#include <libraries/iffparse.h>
#include <dos/dos.h>
#include <exec/libraries.h>
#include <clib/iffparse_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/wb_protos.h>
#include <dos/dosextens.h>
#include <exec/memory.h>
#include "HiddenLists.h"
#define ID_WBGB MAKE_ID('W','B','G','B')
#define SHOW_IF_VALID 1
static struct List Originallist;
extern BOOL catchmouse;
int IsOriginalList(char *Device)
{
    struct Node *node;
    int foundentry = 1;
    for(node = Originallist.lh_Head; node && foundentry && node->ln_Succ; node = node->ln_Succ)
    {
        if(!strcmp(Device,node->ln_Name))
            foundentry=0;
    }
    return(1-foundentry);
}
int IsHiddenDevice(char *Device)
{
    struct List *currentlist;
    int foundentry = 1;
    struct Node *node;
    if(WorkbenchControl(NULL,WBCTRLA_GetHiddenDeviceList,&currentlist,TAG_DONE))
    {
        for(node = currentlist->lh_Head ; node && node->ln_Succ && foundentry; node = node->ln_Succ)
        {
            if(!strcmp(Device,node->ln_Name))
                foundentry=0;
        }
        WorkbenchControl(NULL,WBCTRLA_FreeHiddenDeviceList,currentlist,TAG_DONE);
    }
    return(1-foundentry);
}

int BuildOriginalList()
{
    struct IFFHandle *iff;
    struct ContextNode *top;
    struct Node *Newnode;
    long error;
    int flag=1;
    ULONG showflag;
    catchmouse = FALSE;
    NewList(&Originallist);
    if(iff=AllocIFF())
    {
        iff->iff_Stream=Open("ENV:sys/workbench.prefs",MODE_OLDFILE);
        InitIFFasDOS (iff);
        OpenIFF(iff,IFFF_READ);
        while(flag)
        {
            error=ParseIFF(iff,IFFPARSE_RAWSTEP);
            if (error != IFFERR_EOC)
            {
                if (error != 0 && error !=IFFERR_EOC)
                {
                    flag=0;
                }
                else
                {
                    if(top = CurrentChunk (iff))
                    {
                        if (top->cn_ID == ID_WBNC)
                        {
                            if(top->cn_Size == sizeof(struct Workbench39Prefs))
                            {
                                struct Workbench39Prefs wbprefs;
                                ReadChunkBytes(iff,&wbprefs,sizeof(struct Workbench39Prefs));
                                if(wbprefs.wbp_ShowTitleBar == 2)
                                    catchmouse = TRUE;
                            }
                        }
                        if (top->cn_ID == ID_WBGB)
                        {
                            if(Newnode = (struct Node *)malloc(sizeof(struct Node)))
                            {
                                Newnode->ln_Name = (STRPTR)malloc(top->cn_Size);
                                ReadChunkBytes(iff,&showflag,sizeof(ULONG));
                                ReadChunkBytes(iff,Newnode->ln_Name,top->cn_Size-sizeof(ULONG));
                                if(showflag == SHOW_IF_VALID)
                                    AddTail(&Originallist,Newnode);
                            }
                        }
                    }
                }
            }
        }
        CloseIFF(iff);
        Close(iff->iff_Stream);
        FreeIFF(iff);
    }
}

int FreeOriginalList()
{
    struct Node *currentnode;
    while(currentnode=RemHead(&Originallist))
    {
        free(currentnode->ln_Name);
        free(currentnode);
    }
    /* free up the original list - may need to rebuild if prefs change */
}

void CheckInserted()
{
    /* scan the doslist - if volume present on volume list and on */
    /* current hidden list then remove from current hidden list */
    char VolumeName[10];
    char *ColonPtr;
    struct DosList *dl;
    if(dl=LockDosList(LDF_VOLUMES | LDF_READ))
    {
        while(dl=NextDosEntry(dl,LDF_VOLUMES))
        {
            if(dl->dol_Task)
            {
                memset(VolumeName,'\0',10);
                strcpy(VolumeName,((struct Task *)dl->dol_Task->mp_SigTask)->tc_Node.ln_Name);
                if(ColonPtr=strchr(VolumeName,'\0'))
                    *ColonPtr=':';
                if (IsOriginalList(VolumeName) && IsHiddenDevice(VolumeName))
                {
                    WorkbenchControl(NULL,WBCTRLA_RemoveHiddenDeviceName,VolumeName,TAG_DONE);
                }
            }
        }
        UnLockDosList(LDF_VOLUMES | LDF_READ);
    }
}

void CheckRemoved()
{
    struct Node *Originalnode;
    struct DosList *dl;
    int notfound = 1;
    char *ColonPtr;
    char VolumeName[10];
    for(Originalnode=Originallist.lh_Head;Originalnode->ln_Succ != NULL; Originalnode = Originalnode->ln_Succ)
    {
        if(!IsHiddenDevice(Originalnode->ln_Name))
        {
            if(dl=LockDosList(LDF_VOLUMES | LDF_READ))
            {
                notfound=1;
                while(notfound && (dl=NextDosEntry(dl,LDF_VOLUMES)))
                {
                    if(dl->dol_Task)
                    {
                        memset(VolumeName,'\0',10);
                        strcpy(VolumeName,((struct Task *)dl->dol_Task->mp_SigTask)->tc_Node.ln_Name);
                        if(ColonPtr=strchr(VolumeName,'\0'))
                            *ColonPtr=':';
                        if(!strcmp(VolumeName,Originalnode->ln_Name))
                            notfound=0;
                    }
                }
                UnLockDosList(LDF_VOLUMES | LDF_READ);
                if(notfound)
                {
                    WorkbenchControl(NULL,WBCTRLA_AddHiddenDeviceName,Originalnode->ln_Name,TAG_DONE);
                    /* add hidden device */
                }
            }
        }
    }
    /* scan the original list. if volume not present on volume list */
    /* and not present on current list then add to hidden list */
}

void NewPrefsFound()
{
    /* release the old list, and rebuild it to the new preferences */
    /* and re-check for valid drives */
    FreeOriginalList();
    BuildOriginalList();
}
