#include <clib/dos_protos.h>
#include <clib/iffparse_protos.h>
#include <gadgets/listbrowser.h>
#include <string.h>
#include <prefs/prefhdr.h>
#include <prefs/workbench.h>
#include "GUIFuncs.h"
extern struct Window *ra_window;
extern UBYTE *col2[];
struct List label_list;
UWORD NewIcons_Option = 0;
UWORD ColourIcon_Option = 0;
UWORD Quality_Option = 1;
UWORD Border_Option = 1;
UWORD Stack_Value = 8;
UWORD Delay_Value = 3;
struct EasyStruct ifferror =
{
    sizeof(struct EasyStruct),
    0,
    NULL,
    NULL,
    NULL
};
struct EasyStruct fileerror =
{
    sizeof(struct EasyStruct),
    0,
    NULL,
    NULL,
    NULL
};
long precisions[] =
{
    PRECISION_GUI,
    PRECISION_ICON,
    PRECISION_IMAGE,
    PRECISION_EXACT
};
BOOL LoadSettings(char *filename)
{
    struct IFFHandle *iff;
    struct ContextNode *top;
    struct WorkbenchPrefs wbprefs;
    struct ListerNode *node;
    long error;
    int flag=1;
    int countparse=0;
    char *DeviceName;
    if(iff=AllocIFF())
    {
        if(iff->iff_Stream=Open(filename,MODE_OLDFILE))
        {
            InitIFFasDOS (iff);
            OpenIFF(iff,IFFF_READ);
            while(flag)
            {
                error=ParseIFF(iff,IFFPARSE_RAWSTEP);
                if (error != IFFERR_EOC)
                {
                    countparse++;
                    if (error != 0)
                    {
                        if(error != IFFERR_EOF)
                            EasyRequest(ra_window,&ifferror,NULL,filename);
                        flag=0;
                    }
                    else
                    {
                        if(top = CurrentChunk (iff))
                        {
                            switch (countparse)
                            {
                                case 1:
                                    if(top->cn_ID != ID_FORM)
                                    {
                                        EasyRequest(ra_window,&ifferror,NULL,filename);
                                        flag=0;
                                    }
                                    break;
                                case 2:
                                    if(top->cn_ID != ID_PRHD)
                                    {
                                        EasyRequest(ra_window,&ifferror,NULL,filename);
                                        flag=0;
                                    }
                                    break;
                                default:
                                    if (top->cn_ID == ID_WBNC)
                                    {
                                        Free_List(&label_list);
                                        Make_List(&label_list, col2);
                                        ReadChunkBytes(iff,&wbprefs,sizeof(struct WorkbenchPrefs));
                                        Stack_Value = wbprefs.wbp_DefaultStackSize/1024;
                                        Delay_Value = wbprefs.wbp_TypeRestartTime;
                                        ColourIcon_Option = 1 - wbprefs.wbp_ColorIconSupport;
                                        NewIcons_Option = 1 - wbprefs.wbp_NewIconsSupport;
                                        switch(wbprefs.wbp_IconPrecision)
                                        {
                                            case PRECISION_GUI:
                                                Quality_Option = 0;
                                                break;
                                            case PRECISION_ICON:
                                                Quality_Option = 1;
                                                break;
                                            case PRECISION_IMAGE:
                                                Quality_Option = 2;
                                                break;
                                            case PRECISION_EXACT:
                                                Quality_Option = 3;
                                                break;
                                            default:
                                                Quality_Option = 1;
                                                break;
                                        }
                                        if(wbprefs.wbp_Borderless)
                                            Border_Option = 0;
                                        else
                                        {
                                            switch(wbprefs.wbp_EmbossRect.MaxX)
                                            {
                                                case 1:
                                                    Border_Option = 1;
                                                    break;
                                                case 2:
                                                    Border_Option = 2;
                                                    break;
                                                case 3:
                                                    Border_Option = 3;
                                                    break;
                                                default:
                                                    Border_Option = 1;
                                                    break;
                                            }
                                        }
                                    }
                                    if (top->cn_ID == ID_WBHD)
                                    {
                                        if(DeviceName=(char *)malloc(sizeof(char) * top->cn_Size))
                                        {
                                            ReadChunkBytes(iff,DeviceName,top->cn_Size);
                                            if(node=MyFindNode(&label_list,DeviceName))
                                            {
                                                if(node->option == 0)
                                                {
                                                    node->option=1;
                                                    SetListBrowserNodeAttrs((struct Node *)node,
                                                        LBNA_Column,1,
                                                        LBNCA_Text,col2[node->option],
                                                        TAG_END);
                                                }
                                                free(DeviceName);
                                            }
                                            else
                                            {
                                                if (node = (struct ListerNode *)AllocListBrowserNode(2,
                                                    LBNA_NodeSize, sizeof(struct ListerNode),
                                                    LBNA_Column, 0,
                                                    LBNCA_Text, DeviceName,
                                                    LBNA_Column, 1,
                                                    LBNCA_Text, col2[1],
                                                    TAG_DONE))
                                                {
                                                    node->device=DeviceName;
                                                    node->volume=NULL;
                                                    node->option=1;
                                                    node->mounted=FALSE;
                                                    AddTail(&label_list,(struct Node *)node);
                                                }
                                            }
                                        }
                                    }
                                    if (top->cn_ID == ID_WBGB)
                                    {
                                        if(DeviceName=(char *)malloc(top->cn_Size-sizeof(ULONG)))
                                        {
                                            ULONG flag = 0;
                                            ReadChunkBytes(iff,&flag,sizeof(ULONG));
                                            ReadChunkBytes(iff,DeviceName,top->cn_Size-sizeof(ULONG));
                                            if(node=MyFindNode(&label_list,DeviceName))
                                            {
                                                node->option=flag;
                                                SetListBrowserNodeAttrs((struct Node *)node,
                                                    LBNA_Column,1,
                                                    LBNCA_Text,col2[node->option],
                                                    TAG_END);
                                                free(DeviceName);
                                            }
                                            else
                                            {
                                                if (node = (struct ListerNode *)AllocListBrowserNode(2,
                                                    LBNA_NodeSize, sizeof(struct ListerNode),
                                                    LBNA_Column, 0,
                                                    LBNCA_Text, DeviceName,
                                                    LBNA_Column, 1,
                                                    LBNCA_Text, col2[flag],
                                                    TAG_DONE))
                                                {
                                                    node->device=DeviceName;
                                                    node->volume=NULL;
                                                    node->option=flag;
                                                    node->mounted=FALSE;
                                                    AddTail(&label_list,(struct Node *)node);
                                                }
                                            }
                                        }
                                    }
                                    break;
                            }
                        }
                    }
                }
            }
            CloseIFF(iff);
            Close(iff->iff_Stream);
        }
        else
        {
            char errorbuf[30];
            Fault(IoErr(),NULL,errorbuf,30);
            EasyRequest(ra_window,&fileerror,NULL,filename,errorbuf);
        }
        FreeIFF(iff);
    }
}
BOOL SavePrefs(char *Filename,BOOL envflag)
{
    struct IFFHandle *iff = NULL;
    long error = 0;
    BOOL returnflag = TRUE;
    struct PrefHeader prhdr =
    {
        0,0,0
    };

    if (iff = AllocIFF())
    {
        if (iff->iff_Stream = Open (Filename, MODE_NEWFILE))
        {

            InitIFFasDOS(iff);
            if(!(error=OpenIFF(iff,IFFF_WRITE)))
            {
                error=PushChunk(iff,ID_PREF,ID_FORM,IFFSIZE_UNKNOWN);
                error+=PushChunk(iff,ID_PREF,ID_PRHD,IFFSIZE_UNKNOWN);
                if((error == 0) && (WriteChunkBytes(iff,(APTR)&prhdr,sizeof(struct PrefHeader)) == sizeof(struct PrefHeader)))
                {
                    struct WorkbenchPrefs wbprefs;
                    PopChunk(iff);
                    error = PushChunk (iff, NULL, ID_WBNC, IFFSIZE_UNKNOWN);
                    wbprefs.wbp_DefaultStackSize=Stack_Value * 1024;
                    wbprefs.wbp_TypeRestartTime = Delay_Value;
                    wbprefs.wbp_ColorIconSupport = 1 - ColourIcon_Option;
                    wbprefs.wbp_NewIconsSupport = 1 - NewIcons_Option;
                    if(Border_Option)
                    {
                        wbprefs.wbp_Borderless = FALSE;
                        wbprefs.wbp_EmbossRect.MaxX = wbprefs.wbp_EmbossRect.MaxY = 1 * Border_Option;
                        wbprefs.wbp_EmbossRect.MinX = wbprefs.wbp_EmbossRect.MinY = -1 * Border_Option;
                    }
                    else
                    {
                        wbprefs.wbp_Borderless = TRUE;
                        wbprefs.wbp_EmbossRect.MaxX = wbprefs.wbp_EmbossRect.MaxY = 1;
                        wbprefs.wbp_EmbossRect.MinX = wbprefs.wbp_EmbossRect.MinY = -1;

                    }
                    wbprefs.wbp_MaxNameLength = 25;
                    wbprefs.wbp_IconPrecision = precisions[Quality_Option];
                    if((error == 0) && (WriteChunkBytes(iff,(APTR)&wbprefs,sizeof(struct WorkbenchPrefs)) == sizeof(struct WorkbenchPrefs)))
                    {
                        struct ListerNode *lNode;
                        PopChunk(iff);
                        for(lNode = (struct ListerNode *)label_list.lh_Head;lNode && lNode->lb_Node.ln_Succ;lNode=(struct ListerNode *)lNode->lb_Node.ln_Succ)
                        {
                            if(envflag)
                            {
                                if((lNode->option == 2) || (lNode->option == 1 && lNode->volume == NULL))
                                {
                                    PushChunk(iff,NULL,ID_WBHD,IFFSIZE_UNKNOWN);
                                    WriteChunkBytes (iff, (APTR) lNode->device, strlen(lNode->device)+1);
                                    PopChunk(iff);
                                }
                            }
                            else
                            {
                                if(lNode->option)
                                {
                                    PushChunk(iff,NULL,ID_WBHD,IFFSIZE_UNKNOWN);
                                    WriteChunkBytes (iff, (APTR) lNode->device, strlen(lNode->device)+1);
                                    PopChunk(iff);
                                }
                            }
                        }
                    for(lNode = (struct ListerNode *)label_list.lh_Head;lNode && lNode->lb_Node.ln_Succ;lNode=(struct ListerNode *)lNode->lb_Node.ln_Succ)
                        {
                            PushChunk(iff,NULL,ID_WBGB,IFFSIZE_UNKNOWN);
                            WriteChunkBytes (iff,(APTR)&(lNode->option),sizeof(ULONG));
                            WriteChunkBytes (iff,(APTR)lNode->device,strlen(lNode->device)+1);
                            PopChunk(iff);
                        }
                    }
                    else
                    {
                        EasyRequest(ra_window,&ifferror,NULL,Filename);
                        returnflag=FALSE;
                    }
                    PopChunk(iff);
                }
                else
                {
                    EasyRequest(ra_window,&ifferror,NULL,Filename);
                    returnflag=FALSE;
                }
            }
            else
            {
                EasyRequest(ra_window,&ifferror,NULL,Filename);
                returnflag=FALSE;
            }
            Close(iff->iff_Stream);
        }
        else
        {
            char errorbuf[30];
            Fault(IoErr(),NULL,errorbuf,30);
            EasyRequest(ra_window,&fileerror,NULL,Filename,errorbuf);
        }
        FreeIFF(iff);
    }
    else
    {
        EasyRequest(ra_window,&ifferror,NULL,Filename);
        returnflag=FALSE;
    }
    return(returnflag);
}
/* Function to make a List of ListBrowserNodes from a couple of arrays.
 * Just to demonstrate things, we make make three columns, 2 with text
 * (the same text) and the third with numbers.
 */
BOOL Make_List(struct List *list, UBYTE **labels2)
{
    struct ListerNode *node;
    struct DosList *dl;
    char *DeviceName;
    char *VolumeName;
    char *ColonPtr;

    if(dl=LockDosList(LDF_DEVICES | LDF_READ))
    {
        while(dl=NextDosEntry(dl,LDF_DEVICES))
        {
            if(dl->dol_Task)
            {
                DeviceName=BCPL2STRPTR(dl->dol_Name);
                if (node = MyFindNode(list,DeviceName))
                {
                    if(node->volume)
                    {
                        SetListBrowserNodeAttrs((struct Node *)node,
                            LBNA_Column,0,
                            LBNCA_Text,node->device,
                            TAG_END);
                        free(node->volume);
                        node->volume = NULL;
                        node->mounted=TRUE;
                    }
                    free(DeviceName);
                }
                else
                {
                    if (node = (struct ListerNode *)AllocListBrowserNode(2,
                        LBNA_NodeSize, sizeof(struct ListerNode),
                        LBNA_Column, 0,
                            LBNCA_Text, DeviceName,
                        LBNA_Column, 1,
                            LBNCA_Text, labels2[0],
                        TAG_DONE))
                    {
                        node->device=DeviceName;
                        node->volume=NULL;
                        node->option=0;
                        node->mounted=TRUE;
                        AddTail(list,(struct Node *)node);
                    }
                }
            }
        }
        UnLockDosList(LDF_DEVICES | LDF_READ);
        for(node = (struct ListerNode *)list->lh_Head;node && node->lb_Node.ln_Succ;)
        {
            if(node->mounted)
            {
                if(!(IsFileSystem(node->device)))
                {
                    struct ListerNode *nextnode;
                    if(node->volume) free(node->volume);
                    if(node->device) free(node->device);
                    nextnode = (struct ListerNode *)node->lb_Node.ln_Succ;
                    Remove((struct Node *)node);
                    node=nextnode;
                }
                else
                    node=(struct ListerNode *)node->lb_Node.ln_Succ;
            }
            else
                node=(struct ListerNode *)node->lb_Node.ln_Succ;
 
        }

    }
    if(dl=LockDosList(LDF_VOLUMES | LDF_READ))
    {
        while(dl=NextDosEntry(dl,LDF_VOLUMES))
        {
            if(dl->dol_Task)
            {
                DeviceName=(char *)malloc(strlen(((struct Task *)dl->dol_Task->mp_SigTask)->tc_Node.ln_Name)+2);
                strcpy(DeviceName,((struct Task *)dl->dol_Task->mp_SigTask)->tc_Node.ln_Name);
                if(ColonPtr=strchr(DeviceName,'\0'))
                {
                    *ColonPtr++=':';
                    *ColonPtr='\0';
                }
                VolumeName=BCPL2STRPTR(dl->dol_Name);
                if(node=MyFindNode(list,DeviceName))
                {
                    SetListBrowserNodeAttrs((struct Node *)node,
                                            LBNA_Column,0,
                                            LBNCA_Text,VolumeName,
                                            TAG_END);
                    node->volume=VolumeName;
                }
            }
        }
        UnLockDosList(LDF_VOLUMES | LDF_READ);
    }
    return(TRUE);
}

/* Function to free an Exec List of ListBrowser nodes.
 */
void Free_List(struct List *list)
{
    struct ListerNode *node;
    while (node = (struct ListerNode *)RemHead(list))
    {
        free(node->device);
        if(node->volume)
            free(node->volume);
        FreeListBrowserNode((struct Node *)node);
    }
    NewList(list);
}

STRPTR BCPL2STRPTR(BSTR s)
{
    STRPTR ris;
    STRPTR eq;

    if (!s)
        return(NULL);
    eq=(STRPTR)BADDR(s);
    if (!eq[0])
        return(NULL);
    ris=(STRPTR)malloc(eq[0] + 2);
    memcpy(ris, eq + 1, eq[0]);
    ris[eq[0]]=':';
    ris[eq[0]+1]=0;
    return(ris);
}
struct ListerNode *MyFindNode(struct List *list, char *Device)
{
    struct ListerNode *node;
    int foundentry;
    for(node = (struct ListerNode *)list->lh_Head; (node) && (foundentry=strcmp(Device,node->device)); node = (struct ListerNode *)node->lb_Node.ln_Succ);
    if(foundentry)
        return(NULL);
    else
        return(node);
}
