/***********************/
/*  Skandalfo's Clock  */
/*---------------------*/
/* See AmigaGuide doc  */
/* for Copyright and   */
/* Licence.            */
/***********************/

#define VERSION "1.1"

#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/locale.h>
#include <libraries/gadtools.h>
#include <libraries/screennotify.h>
#include <proto/intuition.h>
#include <dos/dos.h>
#include <dos/datetime.h>
#include <proto/dos.h>
#include <exec/exec.h>
#include <proto/exec.h>
#include <workbench/startup.h>
#include <proto/icon.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <graphics/displayinfo.h>
#include <graphics/rastport.h>
#include <proto/graphics.h>
#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>
#include <datatypes/soundclass.h>
#include <proto/screennotify.h>
#include <proto/datatypes.h>
#include <devices/timer.h>
#include <libraries/diskfont.h>
#include <proto/timer.h>
#include <proto/gadtools.h>
#include <proto/locale.h>
#include <proto/diskfont.h>

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/****************/
/* GLOBLAL VARS */
/****************/

#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
#endif
#define sgn(a) (((a)>0)?1:-1)

static char versionstring[]="$VER: SkandalfoClock " VERSION " " __AMIGADATE__;

struct Screen *sc=NULL;
struct Window *wi=NULL;
struct DrawInfo *di=NULL;
struct ExtGadget *ga,*db=NULL,*sg=NULL;
APTR gr=NULL,sr=NULL;

struct RastPort rpbackgd,rpbuffer;
struct BitMap *backgd=NULL,*buffer=NULL,*remapped=NULL,*trans=NULL;

struct TmpRas tmpras,tr2;
UBYTE *tmprasbuf=NULL;

struct AreaInfo areainfo,ai2;
#define MAXVECTORS 100
char areabuf[5*MAXVECTORS];

Object *dto=NULL;
struct dtFrameBox dtf;
struct FrameInfo fri;
struct gpLayout gpl;
struct BitMapHeader *bmh;

char psname[257]="Workbench";

Object *hso=NULL,*qso=NULL,*aso=NULL;
char hsfn[257]="",qsfn[257]="",asfn[257]="";
enum chimestype
{
        CNONE,CSINGLE,CMULTIPLE
} chimestype=CNONE;

int co[60],si[60];
int co2[60],si2[60];

enum windowtype
{
        WNORMAL,WBACKDROP
} windowtype=WNORMAL;
enum bordertype 
{
        BNONE, BSINGLE, BDOUBLE
} bordertype=BDOUBLE;

enum borderlook
{
        BNORMAL, BRECESSED
} borderlook=BNORMAL;

enum backtype
{
        BCOLOUR,BIMAGE,BTRANSPARENT
} backtype=BCOLOUR;

BOOL oval=FALSE;
BOOL seconds=TRUE;

enum showwhat
{
        SWNOTHING,SWTWELVE,SWQUARTERS,SWHOURS,SWMINUTES
} showwhat=SWHOURS;

enum showdate
{
    SDNONE,SDNORMAL,SDSHADOW
} showdate=SDNONE;


char backimage[257]="";

int borderwidth=1;

int borderheight=1;

BOOL windowadjustable=TRUE;
BOOL sizeaspicture=FALSE;

int windowleftedge=0;
int windowtopedge=0;
int windowwidth=100;
int windowheight=100;

int buffw=0,buffh=0;
int transw=0,transh=0;
int transcounter=0;

BOOL wpactive=FALSE;

int *hour,*minute,*second;
int *twelve,*quarters,*hours,*minutes;

struct colour
{
        enum colourtype
        {
                INDEX,RGB
        } type;
        int index;
        int R,G,B;
};

struct colour backcolour=
{
        INDEX,0,0,0,0
};

struct colour hour1=
{
        INDEX,1,0,0,0
},minute1=
{
        INDEX,1,0,0,0
},second1=
{
        INDEX,-1,0,0,0
},twelve1=
{
        INDEX,2,0,0,0
},quarters1=
{
        INDEX,2,0,0,0
},hours1=
{
        INDEX,1,0,0,0
},minutes1=
{
        INDEX,3,0,0,0
};

struct colour hour2=
{
        INDEX,3,0,0,0
},minute2=
{
        INDEX,3,0,0,0
},second2=
{
        INDEX,-1,0,0,0
},twelve2=
{
        INDEX,1,0,0,0
},quarters2=
{
        INDEX,1,0,0,0
},hours2=
{
        INDEX,1,0,0,0
},minutes2=
{
        INDEX,3,0,0,0
};

struct colour date1=
{
    INDEX,2,0,0,0
}, date2=
{
    INDEX,1,0,0,0
};

char datefont[257]="topaz.font";

struct TextFont *datef=NULL;
struct TextAttr dateta=
{
    datefont,
    8,
    0,
    0
};

char hourf[257]="data/hour.fig",
     minutef[257]="data/minute.fig",
     secondf[257]="data/second.fig",
     twelvef[257]="data/twelve.fig",
     quartersf[257]="data/quarters.fig",
     hoursf[257]="data/hours.fig",
     minutesf[257]="data/minutes.fig";

char homedir[257]="";

#define MENU_ABOUT                      1
#define MENU_QUIT                       2
#define MENU_ALARMSWITCH        3
#define MENU_ALARMSET           4
#define V(X)                            (void *)X

struct NewMenu scmenu[]=
{
        
        {
                NM_TITLE,       "Project",              0,0,0,0
        },
        {
                NM_ITEM,        "About...",             "?",0,0,V(MENU_ABOUT)
        },
        {
                NM_ITEM,        "Quit",                 "Q",0,0,V(MENU_QUIT)
        },
        {
                NM_TITLE,       "Settings",             0,0,0,0
        },
        {
                NM_ITEM,        "Alarm",                0,0,0,0
        },
        {
                NM_SUB,         "On",                   0,CHECKIT,0,V(MENU_ALARMSWITCH)
        },
        {
                NM_SUB,         "Set...",               0,0,0,V(MENU_ALARMSET)
        },
        {
                NM_END,         0,                              0,0,0,0
        }
};

APTR vi=NULL;
struct Menu *menu=NULL;

int alarmhours=0,alarmminutes=0,alarmcycles=1;
BOOL alarmon=FALSE;
BOOL alarmflag=FALSE;
struct Window *awi=NULL;
struct Gadget *glist=NULL,*slhoursgad,*slminutesgad,*textgad,*usegad,*cancelgad;
int awiiw,awiih;
char alarmstr[10];
                        
#define ID_HOURS 69
#define ID_MINUTES 70
#define ID_TEXT 71
#define ID_USE 72
#define ID_CANCEL 73
                        
/*******************/
/* END GLOBAL VARS */
/*******************/

/************************/
/* BEGIN LOCALE SUPPORT */
/************************/

struct Library *ScreenNotifyBase=NULL;
struct Library *LocaleBase=NULL;
struct Catalog *catalog=NULL;

enum localemsg
{
        MSG_PROJECT=0,
        MSG_ABOUT,
        MSG_ABOUTKEY,
        MSG_QUIT,
        MSG_QUITKEY,
        MSG_SETTINGS,
        MSG_ALARM,
        MSG_ON,
        MSG_SET,
        MSG_SETALARM,   
        MSG_HOURS,              
        MSG_MINUTES,    
        MSG_USE,                
        MSG_CANCEL,             
        MSG_ABOUTTEXT,  
        MSG_ABOUTBUTTON 
};

unsigned char *glstr(ULONG num, unsigned char *def)
{
    if(LocaleBase && catalog)
    {
        return GetCatalogStr(catalog,num,def);
    }
    else
        return def;
}

/**********************/
/* END LOCALE SUPPORT */
/**********************/

struct Gadget *CreateGads(void)
{
        struct Gadget *gad;
        struct NewGadget ng;
        struct RastPort rp;
        
        int buttonw,buttonh,labeloff;
        
        char *usestr=glstr(MSG_USE,"Use");
        char *cancelstr=glstr(MSG_CANCEL,"Cancel");
        char *hoursstr=glstr(MSG_HOURS,"Hours");
        char *minutesstr=glstr(MSG_MINUTES,"Minutes");
        
        /* di->dri_Font */
        /* sc->Font */
        
        InitRastPort(&rp);
        SetFont(&rp,di->dri_Font);
        
        /* TextLength(rp,str,count) */
        /* +12,+8 Buttons */
        /* +4,+4  Text    */
        /* 124,+0 Slider  */
        
        if(gad=CreateContext(&glist))
        {
                buttonw=12+max(TextLength(&rp,usestr,strlen(usestr)),TextLength(&rp,cancelstr,strlen(cancelstr)));
                buttonh=8+sc->Font->ta_YSize;
                labeloff=16+max(TextLength(&rp,hoursstr,strlen(hoursstr)),TextLength(&rp,minutesstr,strlen(minutesstr)));
                awiiw=max(labeloff+124+8,16+2*buttonw+8);
                awiih=4*sc->Font->ta_YSize+8+8+4+4+4+4;
                
                sprintf(alarmstr,"%02d:%02d",alarmhours,alarmminutes);
                
                ng.ng_TextAttr=sc->Font;
                ng.ng_VisualInfo=vi;
                ng.ng_LeftEdge=sc->WBorLeft+labeloff;
                ng.ng_TopEdge=sc->WBorTop+(sc->Font->ta_YSize)+4+1;
                ng.ng_Width=124;
                ng.ng_Height=sc->Font->ta_YSize;
                ng.ng_GadgetText=hoursstr;
                ng.ng_GadgetID=ID_HOURS;
                ng.ng_Flags=0;
                slhoursgad=gad=CreateGadget(SLIDER_KIND,gad,&ng,
                                                                        GTSL_MaxLevelLen,3,
                                                                        GTSL_MaxPixelLen,64,
                                                                        GTSL_Min,0,
                                                                        GTSL_Max,23,
                                                                        GTSL_Level,alarmhours,
                                                                        GA_RelVerify,TRUE,
                                                                        GA_FollowMouse,TRUE,
                                                                        GA_Immediate,TRUE,
                                                                        TAG_END);
                                                                        
                ng.ng_TopEdge=sc->WBorTop+(sc->Font->ta_YSize)*2+8+1;
                ng.ng_GadgetText=minutesstr;
                ng.ng_GadgetID=ID_MINUTES;
                slminutesgad=gad=CreateGadget(SLIDER_KIND,gad,&ng,
                                                                        GTSL_MaxLevelLen,3,
                                                                        GTSL_MaxPixelLen,64,
                                                                        GTSL_Min,0,
                                                                        GTSL_Max,59,
                                                                        GTSL_Level,alarmminutes,
                                                                        GA_RelVerify,TRUE,
                                                                        GA_FollowMouse,TRUE,
                                                                        GA_Immediate,TRUE,
                                                                        TAG_END);
                
                ng.ng_TopEdge=sc->WBorTop+(sc->Font->ta_YSize)*3+12+1;
                ng.ng_LeftEdge=sc->WBorLeft+8;
                ng.ng_GadgetText=NULL;
                ng.ng_GadgetID=ID_TEXT;
                ng.ng_Width=awiiw-16;
                ng.ng_Height=sc->Font->ta_YSize+4;
                textgad=gad=CreateGadget(TEXT_KIND,gad,&ng,
                                                                        GTTX_Border,TRUE,
                                                                        GTTX_Justification,GTJ_CENTER,
                                                                        GTTX_Text,alarmstr,
                                                                        TAG_END);

                ng.ng_TopEdge=sc->WBorTop+(sc->Font->ta_YSize)*4+20+1;
                ng.ng_GadgetText=usestr;
                ng.ng_GadgetID=ID_USE;
                ng.ng_Width=buttonw;
                ng.ng_Height=buttonh;
                usegad=gad=CreateGadget(BUTTON_KIND,gad,&ng,
                                                                        TAG_END);

                ng.ng_LeftEdge=awiiw-8-buttonw+sc->WBorLeft;
                ng.ng_GadgetText=cancelstr;
                ng.ng_GadgetID=ID_CANCEL;
                cancelgad=gad=CreateGadget(BUTTON_KIND,gad,&ng,
                                                                        TAG_END);               
        }
        
        return gad;
}

void awiopen(void)
{
        struct Gadget *gad;
        
        if(awi)
                return;
        
        if(gad=CreateGads())
        {
                if(!(awi=OpenWindowTags(NULL,WA_PubScreen,sc,WA_InnerWidth,awiiw,WA_InnerHeight,awiih,
                                                        WA_Gadgets,glist,
                                                        WA_Flags,WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SIMPLE_REFRESH|WFLG_ACTIVATE|WFLG_NEWLOOKMENUS,
                                                        WA_IDCMP,IDCMP_GADGETUP|IDCMP_MOUSEMOVE|IDCMP_GADGETDOWN|IDCMP_REFRESHWINDOW,
                                                        WA_Title,glstr(MSG_SETALARM,"Set Alarm"),TAG_DONE)))
                {
                                                                FreeGadgets(glist);
                }
                else
                {
                        GT_RefreshWindow(awi,NULL);
                        
                }
        }
}

void awiclose(void)
{
        if(awi)
        {
                CloseWindow(awi);
                FreeGadgets(glist);
                awi=NULL;
        }
}

void updatetext(void)
{
        int h,m;

        GT_GetGadgetAttrs(slhoursgad,awi,NULL,GTSL_Level,&h,TAG_DONE);
        GT_GetGadgetAttrs(slminutesgad,awi,NULL,GTSL_Level,&m,TAG_DONE);
        
        sprintf(alarmstr,"%02d:%02d",h,m);
        GT_SetGadgetAttrs(textgad,awi,NULL,GTTX_Text,alarmstr,TAG_DONE);

/*
        DisplayBeep(NULL);
*/
}

void setpen(struct colour *col, char *s)
{
        if(*s=='#')
        {
                col->type=INDEX;
                col->index=atoi(s+1);
        }
        else
        {
                col->type=RGB;
                sscanf(s,"%d,%d,%d",&(col->R),&(col->G),&(col->B));
        }
}

void preparepen(struct colour *col)
{
        if(col->type==RGB)
        {
                col->index=ObtainBestPen(sc->ViewPort.ColorMap,(col->R)|(col->R<<8)|(col->R<<16)|(col->R<<24),(col->G)|(col->G<<8)|(col->G<<16)|(col->G<<24),(col->B)|(col->B<<8)|(col->B<<16)|(col->B<<24),TAG_DONE);
        }
}

void finishpen(struct colour *col)
{
        if(col->type==RGB)
        {
                ReleasePen(sc->ViewPort.ColorMap,col->index);
        }
}

#define drawfig(a,b) drawfigA(a,b,co,si,&rpbuffer)
#define drawfig2(a,b) drawfigA(a,b,co2,si2,&rpbuffer)
#define drawfig3(a,b) drawfigA(a,b,co,si,&rpbackgd)
#define drawfig4(a,b) drawfigA(a,b,co2,si2,&rpbackgd)

void drawfigA(int *fig, int a, int *co, int *si, struct RastPort *rpbuffer)
{
        int centerx,centery;
        int i,x,y,w,h;
        
        if(fig==NULL)
                return;
        
        w=bordertype+borderwidth*(bordertype==BDOUBLE);
        h=bordertype+borderheight*(bordertype==BDOUBLE);
        
        centerx=windowwidth/2-w;
        centery=windowheight/2-h;

        InitArea(&areainfo,areabuf,MAXVECTORS);

        i=fig[0]-1;
        x=fig[1+2*i]*co[a]-fig[2+2*i]*si[a];
        y=-fig[1+2*i]*si[a]-fig[2+2*i]*co[a];
        x=(x*centerx)>>16;
        y=(y*centery)>>16;
        x+=centerx;
        y+=centery;
        AreaMove(rpbuffer,x+w,y+h);
        
        
        for(i=0;i<fig[0];i++)
        {
        x=fig[1+2*i]*co[a]-fig[2+2*i]*si[a];
        y=-fig[1+2*i]*si[a]-fig[2+2*i]*co[a];
        x=(x*centerx)>>16;
        y=(y*centery)>>16;
        x+=centerx;
        y+=centery;
        AreaDraw(rpbuffer,x+w,y+h);
        }
        AreaEnd(rpbuffer);
}

int *readfig(char *name)
{
        FILE *f;
        int l=0;
        int a,b;
        int *p;
        int k;
        
        if(f=fopen(name,"r"))
        {
        while(k=fscanf(f,"%d%d",&a,&b)==2)
        {
                l++;
        }
        fclose(f);
                if(f=fopen(name,"r"))
                {
                        if(p=malloc((l*2+1)*sizeof(int)))
                        {
                                p[0]=l;
                        while(fscanf(f,"%d%d",&a,&b)==2 && l)
                        {
                                l--;
                    p[1+2*l]=a;
                    p[2+2*l]=b;
                        }
                        fclose(f);
                        return p;
                }
                fclose(f);
                }
        }
        return NULL;
}

void initbufferbackgd(void)
{
        int x,y;
        struct DateStamp ds;
        struct DateTime dati;
        char datebuf[160];
        char dn[32],dt[128];

        if(tmprasbuf)
        {
                FreeRaster(tmprasbuf,buffw,buffh);
                tmprasbuf=NULL;
        }

    Forbid();
    buffw=wi->Width;
    buffh=wi->Height;
    Permit();

        if(buffer)
        {
                FreeBitMap(buffer);
                buffer=NULL;
        }
        buffer=AllocBitMap(buffw,buffh,di->dri_Depth,BMF_CLEAR,wi->RPort->BitMap);

        tmprasbuf=AllocRaster(buffw,buffh);

        if(backgd)
        {
                FreeBitMap(backgd);
                backgd=NULL;
        }
        backgd=AllocBitMap(buffw,buffh,di->dri_Depth,BMF_CLEAR,buffer);
        
        InitTmpRas(&tmpras,tmprasbuf,RASSIZE(buffw,buffh));
        InitArea(&areainfo,areabuf,MAXVECTORS);
        InitTmpRas(&tr2,tmprasbuf,RASSIZE(buffw,buffh));
        InitArea(&ai2,areabuf,MAXVECTORS);
        
        rpbuffer.BitMap=buffer;
        rpbuffer.TmpRas=&tmpras;
        rpbuffer.AreaInfo=&areainfo;
        rpbackgd.TmpRas=&tr2;
        rpbackgd.AreaInfo=&ai2;
        rpbackgd.BitMap=backgd;
        
        switch(backtype)
        {
                case BCOLOUR:
                        SetRast(&rpbackgd,backcolour.index);
                        break;
                case BIMAGE:
                        if(trans)
                        {
                                int i,j;
                                
                                for(i=0;i<buffh;i+=transh)
                                        for(j=0;j<buffw;j+=transw)
                                BltBitMap(trans,0,0,backgd,j,i,min(buffw-j,transw),min(buffh-i,transh),0x0C0,0xFF,NULL);
            }
                        break;
                case BTRANSPARENT:
                        if(trans)
                        {
                BltBitMap(trans,0,0,backgd,0,0,min(buffw,transw),min(buffh,transh),0x0C0,0xFF,NULL);
            }
                        break;
        }
        
        if(oval)
        {
                if(showwhat>=SWTWELVE)
                {
                        SetAPen(&rpbackgd,twelve1.index);
                        SetOPen(&rpbackgd,twelve2.index);
                        drawfig3(twelve,0);
                }
                if(showwhat>=SWQUARTERS)
                {
                        SetAPen(&rpbackgd,quarters1.index);
                        SetOPen(&rpbackgd,quarters2.index);
                        drawfig3(quarters,15);
                        drawfig3(quarters,30);
                        drawfig3(quarters,45);
                }
                if(showwhat>=SWHOURS)
                {
                        SetAPen(&rpbackgd,hours1.index);
                        SetOPen(&rpbackgd,hours2.index);
                        drawfig3(hours,5);
                        drawfig3(hours,10);
                        drawfig3(hours,20);
                        drawfig3(hours,25);
                        drawfig3(hours,35);
                        drawfig3(hours,40);
                        drawfig3(hours,50);
                        drawfig3(hours,55);
                }
                if(showwhat>=SWMINUTES)
                {
                        SetAPen(&rpbackgd,minutes1.index);
                        SetOPen(&rpbackgd,minutes2.index);
                        for(y=1;y<60;y++)
                        {
                                if(y%5)
                                {
                                        drawfig3(minutes,y);
                                }
                        }
                }
        }
        else
        {
                if(showwhat>=SWTWELVE)
                {
                        SetAPen(&rpbackgd,twelve1.index);
                        SetOPen(&rpbackgd,twelve2.index);
                        drawfig4(twelve,0);
                }
                if(showwhat>=SWQUARTERS)
                {
                        SetAPen(&rpbackgd,quarters1.index);
                        SetOPen(&rpbackgd,quarters2.index);
                        drawfig4(quarters,15);
                        drawfig4(quarters,30);
                        drawfig4(quarters,45);
                }
                if(showwhat>=SWHOURS)
                {
                        SetAPen(&rpbackgd,hours1.index);
                        SetOPen(&rpbackgd,hours2.index);
                        drawfig4(hours,5);
                        drawfig4(hours,10);
                        drawfig4(hours,20);
                        drawfig4(hours,25);
                        drawfig4(hours,35);
                        drawfig4(hours,40);
                        drawfig4(hours,50);
                        drawfig4(hours,55);
                }
                if(showwhat>=SWMINUTES)
                {
                        SetAPen(&rpbackgd,minutes1.index);
                        SetOPen(&rpbackgd,minutes2.index);
                        for(y=1;y<60;y++)
                        {
                                if(y%5)
                                {
                                        drawfig4(minutes,y);
                                }
                        }
                }
        }

        /* Date drawing */

        ds.ds_Days=ds.ds_Minute=ds.ds_Tick=0;
        DateStamp(&ds);

        if(showdate!=SDNONE)
        {
                dati.dat_Stamp=ds;
                dati.dat_Format=4; /* Locale default? */
                dati.dat_Flags=0;
                dati.dat_StrDay=dn;
                dati.dat_StrDate=dt;
                dati.dat_StrTime=NULL;

                DateToStr(&dati);

                strcpy(datebuf,dn);
                strcat(datebuf,", ");
                strcat(datebuf,dt);

                SetFont(&rpbackgd,datef);
                x=TextLength(&rpbackgd,datebuf,strlen(datebuf));

                if(!(x>windowwidth-(bordertype+borderwidth*(bordertype==BDOUBLE)) || dateta.ta_YSize>windowheight-(bordertype+borderheight*(bordertype==BDOUBLE))))
                {
                    x=(windowwidth-x)/2;
                    y=((windowheight*3)/4-(dateta.ta_YSize)/2);
                    y=min(y,windowheight-(bordertype+borderheight*(bordertype==BDOUBLE))-dateta.ta_YSize);
                    y=max(y,bordertype+borderheight*(bordertype==BDOUBLE));
                    SetDrMd(&rpbackgd,JAM1);
                    if(showdate==SDSHADOW)
                    {
                        SetAPen(&rpbackgd,date2.index);
                        Move(&rpbackgd,x+1,y+1);
                        Text(&rpbackgd,datebuf,strlen(datebuf));
                    }

                    SetAPen(&rpbackgd,date1.index);
                    Move(&rpbackgd,x,y);
                    Text(&rpbackgd,datebuf,strlen(datebuf));
                }
        }


        y=(ds.ds_Minute/12)%60;
        SetAPen(&rpbackgd,hour1.index);
        SetOPen(&rpbackgd,hour2.index);
        drawfig3(hour,y);

        y=ds.ds_Minute%60;
        SetAPen(&rpbackgd,minute1.index);
        SetOPen(&rpbackgd,minute2.index);
        drawfig3(minute,y);

}

void drawborder(void)
{
        int k,ac=0;
        struct RastPort *rp;
        
        rp=wi->RPort;
        
        SetDrMd(rp,JAM1);
        
        if(wi->Flags&WFLG_WINDOWACTIVE)
        {
                ac=1;
        }
        
        switch(bordertype)
        {
                case BNONE:
                        break;
                case BSINGLE:
                        k=borderlook^ac;
                        if(k)
                        {
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,0,0);
                                Draw(rp,wi->Width-1,0);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,0,wi->Height-1);
                                Draw(rp,wi->Width-1,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,0,0);
                                Draw(rp,0,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,wi->Width-1,0);
                                Draw(rp,wi->Width-1,wi->Height-1);
                        }
                        else
                        {
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,0,0);
                                Draw(rp,wi->Width-1,0);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,0,wi->Height-1);
                                Draw(rp,wi->Width-1,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,0,0);
                                Draw(rp,0,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,wi->Width-1,0);
                                Draw(rp,wi->Width-1,wi->Height-1);                              
                        }
                        break;
                case BDOUBLE:
                        k=borderlook;
                        if(k)
                        {
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,0,0);
                                Draw(rp,wi->Width-1,0);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,0,wi->Height-1);
                                Draw(rp,wi->Width-1,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,0,0);
                                Draw(rp,0,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,wi->Width-1,0);
                                Draw(rp,wi->Width-1,wi->Height-1);

                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,1+borderwidth,1+borderheight);
                                Draw(rp,wi->Width-2-borderwidth,1+borderheight);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,1+borderwidth,wi->Height-2-borderheight);
                                Draw(rp,wi->Width-2-borderwidth,wi->Height-2-borderheight);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,1+borderwidth,1+borderheight);
                                Draw(rp,1+borderwidth,wi->Height-2-borderheight);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,wi->Width-2-borderwidth,1+borderheight);
                                Draw(rp,wi->Width-2-borderwidth,wi->Height-2-borderheight);                             
                        }
                        else
                        {
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,0,0);
                                Draw(rp,wi->Width-1,0);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,0,wi->Height-1);
                                Draw(rp,wi->Width-1,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,0,0);
                                Draw(rp,0,wi->Height-1);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,wi->Width-1,0);
                                Draw(rp,wi->Width-1,wi->Height-1);

                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,1+borderwidth,1+borderheight);
                                Draw(rp,wi->Width-2-borderwidth,1+borderheight);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,1+borderwidth,wi->Height-2-borderheight);
                                Draw(rp,wi->Width-2-borderwidth,wi->Height-2-borderheight);
                                SetAPen(rp,di->dri_Pens[SHADOWPEN]);
                                Move(rp,1+borderwidth,1+borderheight);
                                Draw(rp,1+borderwidth,wi->Height-2-borderheight);
                                SetAPen(rp,di->dri_Pens[SHINEPEN]);
                                Move(rp,wi->Width-2-borderwidth,1+borderheight);
                                Draw(rp,wi->Width-2-borderwidth,wi->Height-2-borderheight);                             
                        }
                        
                        if(ac)
                        {
                                SetAPen(rp,di->dri_Pens[FILLPEN]);
                        }
                        else
                        {
                                SetAPen(rp,di->dri_Pens[BACKGROUNDPEN]);
                        }
                        if(borderwidth)
                        {
                                RectFill(rp,1,1,borderwidth,wi->Height-2);
                                RectFill(rp,wi->Width-1-borderwidth,1,wi->Width-2,wi->Height-2);
                        }
                        if(borderheight)
                        {
                                RectFill(rp,1,1,wi->Width-2,borderheight);
                                RectFill(rp,1,wi->Height-1-borderheight,wi->Width-2,wi->Height-2);
                        }
                        
                        break;
        }
}

void draw(BOOL refresh)
{
        int x,y,w,h;
        struct DateStamp ds;
        struct DateTime dati;
        
        static int lastminute=-1,nh=0,nq=0,lastday=-1;

        static char datebuf[160];
        char dn[32],dt[128];
        
        struct dtTrigger dtt=
        {
                DTM_TRIGGER,NULL,STM_PLAY,NULL
        };

        ds.ds_Days=ds.ds_Minute=ds.ds_Tick=0;
        DateStamp(&ds);

        if(ds.ds_Days!=lastday)
        {
                dati.dat_Stamp=ds;
                dati.dat_Format=4; /* Locale default? */
                dati.dat_Flags=0;
                dati.dat_StrDay=dn;
                dati.dat_StrDate=dt;
                dati.dat_StrTime=NULL;
                
                DateToStr(&dati);
                
                strcpy(datebuf,dn);
                strcat(datebuf,", ");
                strcat(datebuf,dt);
                
                SetWindowTitles(wi,NULL,datebuf);
                
                lastday=ds.ds_Days;
        }

        if(!alarmflag && alarmon && ds.ds_Minute==(alarmhours*60+alarmminutes))
        {
                alarmflag=TRUE;
                if(aso)
                {
                        SetDTAttrs (aso, NULL, NULL, SDTA_Cycles, alarmcycles, TAG_END);
                        DoDTMethodA (aso, NULL, NULL, (Msg)&dtt);
                }

        }
        if(alarmflag && ds.ds_Minute!=(alarmhours*60+alarmminutes))
        {
                alarmflag=FALSE;
        }

        y=ds.ds_Minute%60;

        if(lastminute>0 && chimestype==CMULTIPLE)
        {
                if(lastminute<15 && y>=15)
                {
                        nq=1;
                }
                if(lastminute<30 && y>=30)
                {
                        nq=2;
                }
                if(lastminute<45 && y>=45)
                {
                        nq=3;
                }
                if(lastminute>=45 && y<15)
                {
                        nq=4;
                        nh=(ds.ds_Minute/60)%12;
                        if(!nh) nh=12;
                }
                if(!qso) nq=0;
                if(!hso) nh=0;
        }

        if(lastminute>0 && chimestype==CSINGLE)
        {
                if(lastminute<15 && y>=15)
                {
                        nq=1;
                }
                if(lastminute<30 && y>=30)
                {
                        nq=1;
                }
                if(lastminute<45 && y>=45)
                {
                        nq=1;
                }
                if(lastminute>=45 && y<15)
                {
                        nh=1;
                }
                if(!qso) nq=0;
                if(!hso) nh=0;
        }

        if(nq && !((ds.ds_Tick/50)&1))
        {
                nq--;
                if(qso)
                        DoDTMethodA (qso, NULL, NULL, (Msg)&dtt);
        }
        else if(nh && !((ds.ds_Tick/50)&1))
        {
                nh--;
                if(hso)
                        DoDTMethodA (hso, NULL, NULL, (Msg)&dtt);
        }

        if(y!=lastminute)
        {
                initbufferbackgd();
        }

        if(!seconds && y==lastminute && !refresh)
        {
                return;
        }

        lastminute=y;

        BltBitMap(backgd,0,0,buffer,0,0,buffw,buffh,0x0C0,0xFF,NULL);
/*                      
**      x=(ds.ds_Minute/12)%60;
**      SetAPen(&rpbuffer,hour1.index);
**      SetOPen(&rpbuffer,hour2.index);
**      drawfig(hour,x);
**
**      SetAPen(&rpbuffer,minute1.index);
**      SetOPen(&rpbuffer,minute2.index);
**      drawfig(minute,y);
*/
        if(seconds)
        {
                x=(ds.ds_Tick/50)%60;
                SetAPen(&rpbuffer,second1.index);
                SetOPen(&rpbuffer,second2.index);
                drawfig(second,x);
        }
        
        x=bordertype+borderwidth*(bordertype==BDOUBLE);
        y=bordertype+borderheight*(bordertype==BDOUBLE);
        w=buffw-2*x;
        h=buffh-2*y;
        BltBitMapRastPort(buffer,x,y,wi->RPort,x,y,w,h,0x0C0);
}

int wopen(void)
{

        windowwidth=min(windowwidth,sc->Width);
        windowheight=min(windowheight,sc->Height);
        windowleftedge=min(windowleftedge,sc->Width-windowwidth);
        windowtopedge=min(windowtopedge,sc->Height-windowheight);

        if(backtype==BTRANSPARENT && trans)
        {
                FreeBitMap(trans);
                trans=NULL;
        }
        if(backtype==BTRANSPARENT)
        {
        trans=AllocBitMap(windowwidth,windowheight,di->dri_Depth,BMF_CLEAR,sc->RastPort.BitMap);
        transw=windowwidth;
        transh=windowheight;
        if(trans)
        {
                        /*
                        if(wi=OpenWindowTags(NULL,      WA_Width,windowwidth,WA_Height,windowheight,WA_Title,NULL,WA_PubScreen,sc,
                                                                                WA_MinWidth,20,WA_MinHeight,20,WA_MaxWidth,65535,WA_MaxHeight,65535,
                                                                                WA_SizeGadget,FALSE,WA_DragBar,FALSE,WA_Borderless,TRUE,
                                                                                WA_Activate,FALSE,
                                                                                WA_BackFill,LAYERS_NOBACKFILL,WA_Backdrop,windowtype,
                                                                                WA_Left,windowleftedge,WA_Top,windowtopedge,
                                                                                TAG_DONE))
                        {
                            Delay(25);
                            BltBitMap(wi->RPort->BitMap,windowleftedge,windowtopedge,trans,0,0,windowwidth,windowheight,0x0C0,0xFF,NULL);
                                CloseWindow(wi);
                        }
                        else
                        {
                                FreeBitMap(trans);
                                trans=NULL;
                        }
                        */

                        /* New Method */
                        Delay(25);

                        BltBitMap(sc->RastPort.BitMap,windowleftedge,windowtopedge,trans,0,0,windowwidth,windowheight,0x0C0,0xFF,NULL);
                        /* End of New Method */
        }
        }
                
        if(wi=OpenWindowTags(NULL,      WA_Width,windowwidth,WA_Height,windowheight,WA_Title,NULL,WA_PubScreen,sc,
                                                                WA_MinWidth,20,WA_MinHeight,20,WA_MaxWidth,65535,WA_MaxHeight,65535,
                                                                WA_SizeGadget,windowadjustable,WA_DragBar,windowadjustable,WA_Borderless,TRUE,
                                                                WA_Activate,wpactive,WA_SimpleRefresh,TRUE,
                                                                WA_BackFill,LAYERS_NOBACKFILL,WA_Backdrop,windowtype,
                                                                WA_NewLookMenus,TRUE,WA_IDCMP,IDCMP_NEWSIZE|IDCMP_CHANGEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_VANILLAKEY|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MENUPICK,
                                                                WA_Left,windowleftedge,WA_Top,windowtopedge,
                                                                TAG_DONE))
        {
                wi->BorderLeft=wi->BorderRight=wi->BorderTop=wi->BorderBottom=0;
                
                Forbid();               
                ga=(struct ExtGadget *)wi->FirstGadget;
                
                db=sg=NULL;
                
                while(ga)
                {
                        if(((ga->GadgetType)&(GTYP_SYSTYPEMASK))==(GTYP_WDRAGGING))
                        {
                                db=ga;
                        }
                        if(((ga->GadgetType)&(GTYP_SYSTYPEMASK))==(GTYP_SIZING))
                        {
                                sg=ga;
                        }
                        ga=ga->NextGadget;
                }
                if(db && sg)
                {
                        db->Height=-sg->Height;
                        db->Flags|=GFLG_RELHEIGHT;
                
                        gr=sg->GadgetRender;
                        sr=sg->SelectRender;
                
                        sg->GadgetRender=NULL;
                        sg->SelectRender=NULL;
                }
                Permit();
                
                if(backtype==BCOLOUR)
                {
                        preparepen(&backcolour);
                }
                preparepen(&hour1);
                preparepen(&minute1);
                preparepen(&second1);
                preparepen(&twelve1);
                preparepen(&quarters1);
                preparepen(&hours1);
                preparepen(&minutes1);
                preparepen(&hour2);
                preparepen(&minute2);
                preparepen(&second2);
                preparepen(&twelve2);
                preparepen(&quarters2);
                preparepen(&hours2);
                preparepen(&minutes2);
                preparepen(&date1);
                preparepen(&date2);

                datef=OpenDiskFont(&dateta);

                InitRastPort(&rpbuffer);
                InitRastPort(&rpbackgd);

                initbufferbackgd();
                drawborder();
                draw(TRUE);
                
                SetMenuStrip(wi,menu);
                
                return 1;
        }
        else
        {
                return 0;
        }
}

void wclose(void)
{
        if(tmprasbuf)
        {
                FreeRaster(tmprasbuf,buffw,buffh);
                tmprasbuf=NULL;
        }

        if(trans && backtype==BTRANSPARENT)
        {
                FreeBitMap(trans);
                trans=NULL;
        }
        if(backgd)
        {
                FreeBitMap(backgd);
                backgd=NULL;
        }
        if(buffer)
        {
                FreeBitMap(buffer);
                buffer=NULL;
        }

        if(backtype==BCOLOUR)
        {
                finishpen(&backcolour);
        }
        finishpen(&hour1);
        finishpen(&minute1);
        finishpen(&second1);
        finishpen(&twelve1);
        finishpen(&quarters1);
        finishpen(&hours1);
        finishpen(&minutes1);
        finishpen(&hour2);
        finishpen(&minute2);
        finishpen(&second2);
        finishpen(&twelve2);
        finishpen(&quarters2);
        finishpen(&hours2);
        finishpen(&minutes2);
        finishpen(&date1);
        finishpen(&date2);

        if(datef)
        {
            CloseFont(datef);
            datef=NULL;
        }

        if(db && sg)
        {
                sg->GadgetRender=gr;
                sg->SelectRender=sr;
        }
        
        windowleftedge=wi->LeftEdge;
        windowtopedge=wi->TopEdge;
        windowwidth=wi->Width;
        windowheight=wi->Height;

        if(wi->Flags&WFLG_WINDOWACTIVE)
        {
                wpactive=TRUE;
        }
        else
        {
                wpactive=FALSE;
    }
    
    ClearMenuStrip(wi);
        CloseWindow(wi);
        wi=NULL;
        db=sg=NULL;
        gr=sr=NULL;
}

int main(int argc, char *argv[])
{
        int rc=20;
        BOOL running=TRUE,noexit=TRUE;
        struct IntuiMessage *im;
        
        struct MsgPort *tmp;
        struct timerequest *tior;
        
        ULONG signals;
        int a;

        struct MsgPort *snmp=NULL;
        APTR snhandle=NULL;
        struct ScreenNotifyMessage *snm=NULL;

        struct EasyStruct aboutes=
        {
                sizeof(struct EasyStruct),
                0,
                "SkandalfoClock "VERSION" "__AMIGADATE__,
                "Written by:\n  Juan J. García de Soria\n  c/ Alte. León Herrero 31, 5ºJ\n  11100 San Fernando (Cádiz)\n  SPAIN\n\nE-mail:\n  amisanf@ctv.es\n  soria@bart.us.es\n\nThis program is (E-MAIL|CARD)WARE:\nIf you use it please send the author\nan e-mail or postcard.",
                "Yes, Sir"
        };

        BPTR oldcd,pdcd;
        struct DiskObject *dobj;
        struct WBStartup *wbs;
        STRPTR s,t;
        char name[257];

        {
                if(!argc)
                {
                        wbs=(struct WBStartup *)argv;
                        oldcd=CurrentDir(wbs->sm_ArgList->wa_Lock);
                        strcpy(name,wbs->sm_ArgList->wa_Name);
                }
                else
                {
                        s=argv[0];
                        t=s;
                        while(*s)
                        {
                                if(*s=='/' || *s==':')
                                {
                                        t=s+1;
                                }
                                s++;
                        }
                        strcpy(name,t);
                        pdcd=Lock("PROGDIR:",ACCESS_READ);
                        oldcd=CurrentDir(pdcd);
                }
                
                if(dobj=GetDiskObject(name))
                {
                        if(s=FindToolType(dobj->do_ToolTypes,"BACKDROP"))
                        {
                                windowtype=WBACKDROP;
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"BORDER"))
                        {
                                if(!strcmp(s,"NONE"))
                                {
                                        bordertype=BNONE;
                                }
                                else if(!strcmp(s,"SINGLE"))
                                {
                                        bordertype=BSINGLE;
                                }
                                else if(!strcmp(s,"DOUBLE"))
                                {
                                        bordertype=BDOUBLE;
                                }
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"CHIMES"))
                        {
                                if(!strcmp(s,"NONE"))
                                {
                                        chimestype=CNONE;
                                }
                                else if(!strcmp(s,"SINGLE"))
                                {
                                        chimestype=CSINGLE;
                                }
                                else if(!strcmp(s,"MULTIPLE"))
                                {
                                        chimestype=CMULTIPLE;
                                }
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"RECESSED"))
                        {
                                borderlook=BRECESSED;
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"NOSECOND"))
                        {
                                seconds=FALSE;
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"BACKTYPE"))
                        {
                                if(!strcmp(s,"COLOUR"))
                                {
                                        backtype=BCOLOUR;
                                }
                                else if(!strcmp(s,"IMAGE"))
                                {
                                        backtype=BIMAGE;
                                }
                                else if(!strcmp(s,"TRANSPARENT"))
                                {
                                        backtype=BTRANSPARENT;
                                }
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"OVAL"))
                        {
                                oval=TRUE;
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"SHOW"))
                        {
                                if(!strcmp(s,"NOTHING"))
                                {
                                        showwhat=SWNOTHING;
                                }
                                else if(!strcmp(s,"TWELVE"))
                                {
                                        showwhat=SWTWELVE;
                                }
                                else if(!strcmp(s,"QUARTERS"))
                                {
                                        showwhat=SWQUARTERS;
                                }
                                else if(!strcmp(s,"HOURS"))
                                {
                                        showwhat=SWHOURS;
                                }
                                else if(!strcmp(s,"MINUTES"))
                                {
                                        showwhat=SWMINUTES;
                                }
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"SHOWDATE"))
                        {
                                if(!strcmp(s,"NONE"))
                                {
                                        showdate=SDNONE;
                                }
                                else if(!strcmp(s,"NORMAL"))
                                {
                                        showdate=SDNORMAL;
                                }
                                else if(!strcmp(s,"SHADOW"))
                                {
                                        showdate=SDSHADOW;
                                }
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"DATEFONT"))
                        {
                                strcpy(datefont,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"DATEFONTSIZE"))
                        {
                                dateta.ta_YSize=atoi(s);
                        }

                        if(s=FindToolType(dobj->do_ToolTypes,"BACKFILE"))
                        {
                                strcpy(backimage,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"PUBSCREEN"))
                        {
                                strcpy(psname,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"QUARTERSOUND"))
                        {
                                strcpy(qsfn,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"HOURSOUND"))
                        {
                                strcpy(hsfn,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"ALARMSOUND"))
                        {
                                strcpy(asfn,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"ALARMCYCLES"))
                        {
                                alarmcycles=atoi(s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"FIXED"))
                        {
                                windowadjustable=FALSE;
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"SIZEASPICTURE"))
                        {
                                sizeaspicture=TRUE;
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"BORDERWIDTH"))
                        {
                                borderwidth=atoi(s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"BORDERHEIGHT"))
                        {
                                borderheight=atoi(s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"TOPEDGE"))
                        {
                                windowtopedge=atoi(s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"LEFTEDGE"))
                        {
                                windowleftedge=atoi(s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"WIDTH"))
                        {
                                windowwidth=atoi(s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"HEIGHT"))
                        {
                                windowheight=atoi(s);
                        }

                        if(s=FindToolType(dobj->do_ToolTypes,"BACKCOLOUR"))
                        {
                                setpen(&backcolour,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"DATEPEN"))
                        {
                                setpen(&date1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"DATESHADOW"))
                        {
                                setpen(&date2,s);
                        }

                        if(s=FindToolType(dobj->do_ToolTypes,"HOUR1"))
                        {
                                setpen(&hour1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"HOUR2"))
                        {
                                setpen(&hour2,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"MINUTE1"))
                        {
                                setpen(&minute1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"MINUTE2"))
                        {
                                setpen(&minute2,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"SECOND1"))
                        {
                                setpen(&second1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"SECOND2"))
                        {
                                setpen(&second2,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"TWELVE1"))
                        {
                                setpen(&twelve1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"TWELVE2"))
                        {
                                setpen(&twelve2,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"QUARTERS1"))
                        {
                                setpen(&quarters1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"QUARTERS2"))
                        {
                                setpen(&quarters2,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"HOURS1"))
                        {
                                setpen(&hours1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"HOURS2"))
                        {
                                setpen(&hours2,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"MINUTES1"))
                        {
                                setpen(&minutes1,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"MINUTES2"))
                        {
                                setpen(&minutes2,s);
                        }

                        if(s=FindToolType(dobj->do_ToolTypes,"HOURFIG"))
                        {
                                strcpy(hourf,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"MINUTEFIG"))
                        {
                                strcpy(minutef,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"SECONDFIG"))
                        {
                                strcpy(secondf,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"TWELVEFIG"))
                        {
                                strcpy(twelvef,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"QUARTERSFIG"))
                        {
                                strcpy(quartersf,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"HOURSFIG"))
                        {
                                strcpy(hoursf,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"MINUTESFIG"))
                        {
                                strcpy(minutesf,s);
                        }
                        if(s=FindToolType(dobj->do_ToolTypes,"HOMEDIR"))
                        {
                                strcpy(homedir,s);
                        }
                        FreeDiskObject(dobj);
                }
                CurrentDir(oldcd);
                if(argc)
                        UnLock(pdcd);

                if(*homedir)
                {
                    pdcd=Lock(homedir,ACCESS_READ);
                    oldcd=CurrentDir(pdcd);
                }

        }

        if(LocaleBase = OpenLibrary("locale.library",38))
        {
                catalog=OpenCatalog(NULL,"skandalfoclock.catalog",NULL);
        }

        aboutes.es_TextFormat=glstr(MSG_ABOUTTEXT,aboutes.es_TextFormat);
        aboutes.es_GadgetFormat=glstr(MSG_ABOUTBUTTON,aboutes.es_GadgetFormat);

        scmenu[0].nm_Label=glstr(MSG_PROJECT,scmenu[0].nm_Label);
        scmenu[1].nm_Label=glstr(MSG_ABOUT,scmenu[1].nm_Label);
        scmenu[2].nm_Label=glstr(MSG_QUIT,scmenu[2].nm_Label);
        scmenu[3].nm_Label=glstr(MSG_SETTINGS,scmenu[3].nm_Label);
        scmenu[4].nm_Label=glstr(MSG_ALARM,scmenu[4].nm_Label);
        scmenu[5].nm_Label=glstr(MSG_ON,scmenu[5].nm_Label);
        scmenu[6].nm_Label=glstr(MSG_SET,scmenu[6].nm_Label);

        scmenu[1].nm_CommKey=glstr(MSG_ABOUTKEY,scmenu[1].nm_CommKey);
        scmenu[2].nm_CommKey=glstr(MSG_QUITKEY,scmenu[2].nm_CommKey);

        for(a=0;a<60;a++)
        {
                co2[a]=co[a]=256*cos(-2*PI*a/60);
                si2[a]=si[a]=256*sin(-2*PI*a/60);
                if(abs(si2[a])>abs(co2[a]))
                {
                        co2[a]=(co2[a]*256)/abs(si2[a]);
                        si2[a]=256*sgn(si2[a]);
                }
                else
                {
                        si2[a]=(si2[a]*256)/abs(co2[a]);
                        co2[a]=256*sgn(co2[a]);
                }
        }
        
        tmp=CreateMsgPort();
        if(!tmp)
        {
                return(rc);
        }
        tior=CreateIORequest(tmp,sizeof(struct timerequest));
        if(!tior)
        {
                DeleteMsgPort(tmp);
                return(rc);
        }
        if(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)tior,0))
        {
                DeleteIORequest((struct IORequest *)tior);
                DeleteMsgPort(tmp);
                return(rc);
        }
        
        tior->tr_time.tv_secs=1;
        tior->tr_time.tv_micro=0;
        tior->tr_node.io_Command=TR_ADDREQUEST;
        SendIO((struct IORequest *)tior);
        
        minute=readfig(minutef);
        hour=readfig(hourf);
        second=readfig(secondf);
        twelve=readfig(twelvef);
        quarters=readfig(quartersf);
        hours=readfig(hoursf);
        minutes=readfig(minutesf);

        /* For screennotify.library: */
        if((strcmp(psname,"Workbench")==0) && (ScreenNotifyBase=OpenLibrary(SCREENNOTIFY_NAME,SCREENNOTIFY_VERSION)))
        {
                if(snmp=CreateMsgPort())
                {
                        if(!(snhandle=AddWorkbenchClient(snmp,0)))
                        {
                                DeleteMsgPort(snmp);
                                snmp=NULL;
                                CloseLibrary(ScreenNotifyBase);
                                ScreenNotifyBase=NULL;
                        }
                }
                else
                {
                        CloseLibrary(ScreenNotifyBase);
                        ScreenNotifyBase=NULL;
                }
        }

        while(noexit)
        {
                noexit=0;
                if(sc=LockPubScreen(psname))
                {
                        if(vi=GetVisualInfo(sc,TAG_DONE))
                        {
                                if(menu=CreateMenus(scmenu,TAG_DONE))
                                {
                                        if(LayoutMenus(menu,vi,GTMN_NewLookMenus,TRUE))
                                        {
                                                if(backtype==BIMAGE)
                                                {
                                                        if(dto=NewDTObject ((APTR)backimage,DTA_GroupID,GID_PICTURE,PDTA_FreeSourceBitMap,TRUE,PDTA_Screen,sc,TRUE,TAG_DONE))
                                                        {
                                                        dtf.MethodID = DTM_FRAMEBOX;
                                                        dtf.dtf_GInfo=NULL;
                                                        dtf.dtf_FrameInfo = &fri;
                                                        dtf.dtf_ContentsInfo = &fri;
                                                        dtf.dtf_SizeFrameInfo = sizeof (struct FrameInfo);
                                                        dtf.dtf_FrameFlags=0;
                        
                                                        if(DoDTMethodA(dto,NULL,NULL,(Msg)&dtf) && fri.fri_Dimensions.Depth)
                                                        {
                                                                transw=fri.fri_Dimensions.Width;
                                                                transh=fri.fri_Dimensions.Height;
                                                                gpl.MethodID=DTM_PROCLAYOUT;
                                                                gpl.gpl_GInfo=NULL;
                                                                gpl.gpl_Initial=1L;
                                                
                                                                DoDTMethodA (dto, NULL, NULL, (Msg)&gpl);
                                
                                                                        GetDTAttrs (dto, PDTA_DestBitMap, &trans, PDTA_BitMapHeader, &bmh, TAG_END);
                                                                if(bmh)
                                                                {
                                                                transw=bmh->bmh_Width;
                                                                        transh=bmh->bmh_Height;
                                                            }
                                                                        if(!trans)
                                                                        {
                                                                                DisposeDTObject(dto);
                                                                                dto=NULL;
                                                                                backtype=BCOLOUR;                                               
                                                                        }
                                                                        if(backtype==BIMAGE && sizeaspicture)
                                                                        {
                                                                                windowwidth=transw;
                                                                                windowheight=transh;
                                                                        }
                                                        }
                                                                else
                                                                {
                                                                        DisposeDTObject(dto);
                                                                        dto=NULL;
                                                                        backtype=BCOLOUR;
                                                                }
                                                        }
                                                        else
                                                        {
                                                                backtype=BCOLOUR;
                                                        }
                                                }
                                                if(chimestype!=CNONE)
                                                {
                                                        if(hsfn[0])
                                                                hso=NewDTObject ((APTR)hsfn,DTA_GroupID,GID_SOUND,TAG_DONE);
                                                        if(qsfn[0])
                                                                qso=NewDTObject ((APTR)qsfn,DTA_GroupID,GID_SOUND,TAG_DONE);
                                                }
                                                if(asfn[0])
                                                        aso=NewDTObject ((APTR)asfn,DTA_GroupID,GID_SOUND,SDTA_Cycles,alarmcycles,TAG_DONE);
                                                        
                                                if(di=GetScreenDrawInfo(sc))
                                                {               
                                                        ULONG iclass;
                                                        UWORD icode;
                                                        APTR iaddr;
                                                        struct MenuItem *item;
                                                        ULONG what;
                                                        
                                                        if(wopen())
                                                        {
                                                                noexit=1;
                                        while(running)
                                            {
                                                                        what=(1L<<(wi->UserPort->mp_SigBit) | (1L<<tmp->mp_SigBit));
                                                                        if(ScreenNotifyBase)
                                                                        {
                                                                                what|=(1L<<snmp->mp_SigBit);
                                                                        }
                                                                        if(awi)
                                                                        {
                                                                                what|=(1L<<awi->UserPort->mp_SigBit);
                                                                        }

                                                signals=Wait(what);
                                
                                                if(ScreenNotifyBase && (signals & (1L<<snmp->mp_SigBit)))
                                                {
                                                        if(snm=(struct ScreenNotifyMessage *)GetMsg(snmp))
                                                        {
                                                                if(snm->snm_Value)
                                                                {
                                                                        ReplyMsg((struct Message *)snm);
                                                                }
                                                                else
                                                                {
                                                                        running=FALSE;
                                                                }
                                                        }
                                                }
                                
                                                if(awi && (signals & (1L<<(awi->UserPort->mp_SigBit))))
                                                {
                                                        a=FALSE;
                                                        while(awi && (im=(struct IntuiMessage *)GT_GetIMsg(awi->UserPort)))
                                                        {
                                                                iclass=im->Class;
                                                                icode=im->Code;
                                                                iaddr=im->IAddress;
                                                                
                                                                GT_ReplyIMsg(im);
                                                                
                                                                switch(iclass)
                                                                {
                                                                        case IDCMP_MOUSEMOVE:
                                                                                a=TRUE;
                                                                                break;
                                                                        case IDCMP_GADGETUP:
                                                                                switch(((struct Gadget *)(iaddr))->GadgetID)
                                                                                {
                                                                                        case ID_HOURS:
                                                                                        case ID_MINUTES:
                                                                                                a=TRUE;
                                                                                                break;
                                                                                        case ID_USE:
                                                                                                GT_GetGadgetAttrs(slhoursgad,awi,NULL,GTSL_Level,&alarmhours,TAG_DONE);
                                                                                                                        GT_GetGadgetAttrs(slminutesgad,awi,NULL,GTSL_Level,&alarmminutes,TAG_DONE);
                                                                                        case ID_CANCEL:
                                                                                                awiclose();
                                                                                                break;
                                                                                }
                                                                                break;
                                                                        case IDCMP_GADGETDOWN:
                                                                                switch(((struct Gadget *)(iaddr))->GadgetID)
                                                                                {
                                                                                        case ID_HOURS:
                                                                                        case ID_MINUTES:
                                                                                                a=TRUE;
                                                                                                break;
                                                                                }
                                                                                break;
                                                                        case IDCMP_REFRESHWINDOW:
                                                                                GT_BeginRefresh(awi);
                                                                                GT_RefreshWindow(awi,NULL);
                                                                                GT_EndRefresh(awi,TRUE);
                                                                                break;
                                                                }
                                                        }
                                                        if(awi && a)
                                                                updatetext();
                                                }
                                
                                                        if(signals & (1L<<(wi->UserPort->mp_SigBit)) )
                                                        {
                                                        while(im=(struct IntuiMessage *)GT_GetIMsg(wi->UserPort))
                                                        {
                                                                iclass=im->Class;
                                                                icode=im->Code;
                                                                
                                                                GT_ReplyIMsg(im);
                                                                
                                                                
                                                                switch(iclass)
                                                        {
                                                                        case IDCMP_NEWSIZE:
                                                                                                        windowleftedge=wi->LeftEdge;
                                                                                                        windowtopedge=wi->TopEdge;
                                                                                                        windowwidth=wi->Width;
                                                                                                        windowheight=wi->Height;
                
                                                                                        drawborder();
                                                                                        initbufferbackgd();
                                                                                        draw(TRUE);
                                                                                        break;
                                                                        case IDCMP_REFRESHWINDOW:
                                                                                BeginRefresh(wi);
                                                                                drawborder();
                                                                                draw(TRUE);
                                                                                EndRefresh(wi,TRUE);
                                                                                break;
                                                                        case IDCMP_VANILLAKEY:
                                                                                if(icode==27)
                                                                                {
                                                                                        running=noexit=0;
                                                                                        }
                                                                                        break;
                                                                        case IDCMP_ACTIVEWINDOW:
                                                                                        drawborder();
                                                                                break;
                                                                        case IDCMP_INACTIVEWINDOW:
                                                                            drawborder();
                                                                                break;
                                                                                case IDCMP_CHANGEWINDOW:
                                                                                windowleftedge=wi->LeftEdge;
                                                                                                        windowtopedge=wi->TopEdge;
                                                                                                        windowwidth=wi->Width;
                                                                                                        windowheight=wi->Height;
                        
                                                                transcounter=2;
                                                                                break;
                                                                        case IDCMP_MENUPICK:
                                                                                item=ItemAddress(menu,icode);
                                                                                if(item)
                                                                                {
                                                                                    switch((int)MENU_USERDATA(item))
                                                                                    {
                                                                                            case MENU_ABOUT:
                                                                                                    SetWindowPointer(wi,WA_BusyPointer,TRUE,TAG_DONE);
                                                                                                    EasyRequest(wi,&aboutes,NULL);
                                                                                                    SetWindowPointer(wi,WA_Pointer,NULL,TAG_DONE);
                                                                                                    break;
                                                                                            case MENU_QUIT:
                                                                                                    running=noexit=0;
                                                                                                    break;
                                                                                            case MENU_ALARMSWITCH:
                                                                                                    if(item->Flags && CHECKED)
                                                                                                    {
                                                                                                            alarmon=TRUE;
                                                                                                    }
                                                                                                    else
                                                                                                    {
                                                                                                            alarmon=FALSE;
                                                                                                    }
                                                                                                    break;
                                                                                            case MENU_ALARMSET:
                                                                                                    awiopen();
                                                                                                    break;
                                                                                    }
                                                                                }
                                                                                break;
                                                                        }
                                                                }
                                                }
                                                if(signals & (1L<<tmp->mp_SigBit))
                                                {
                                                        if(CheckIO((struct IORequest *)tior))
                                                        {
                                                                struct DateStamp ds;
                                                                        int k;
                                                
                                                                        WaitIO((struct IORequest *)tior);
                                                                if(transcounter)
                                                                {
                                                                        if(!--transcounter)
                                                                        {
                                                                                running=1;
                                                                                if(backtype==BTRANSPARENT)
                                                                                {
                                                                                        wclose();
                                                                                        /*Delay(25);*/
                                                                                        wopen();
                                                                                }
                                                                                }
                                                                        else
                                                                                {
                                                                                draw(FALSE);
                                                                                }
                                                                }
                                                                else
                                                                        {
                                                                        draw(FALSE);
                                                                }
                                                                
                                                                ds.ds_Days=ds.ds_Minute=ds.ds_Tick=0;
                                                                DateStamp(&ds);
                                                                        k=(50-ds.ds_Tick%50)*20000;
                                                
                                                                        tior->tr_time.tv_secs=0;
                                                                                        tior->tr_time.tv_micro=k;
                                                                                        tior->tr_node.io_Command=TR_ADDREQUEST;
                                                                                        SendIO((struct IORequest *)tior);
                                                        }
                                                        }
                                            }
                                                                rc=0;
                                                                
                                                                if(awi)
                                                                {
                                                                        awiclose();
                                                                }
                                                                
                                                                wclose();
                                        
                                                                if(trans && backtype!=BIMAGE)
                                                                {
                                                                        FreeBitMap(trans);
                                                                }
                                                        }
                                                        FreeScreenDrawInfo(sc,di);
                                                }
                                                if(dto)
                                                {
                                                        DisposeDTObject(dto);
                                                }
                                
                                                if(aso)
                                                {
                                                        DisposeDTObject(aso);
                                                }
                                                if(hso)
                                                {
                                                        DisposeDTObject(hso);
                                                }
                                                if(qso)
                                                {
                                                        DisposeDTObject(qso);
                                                }
                                        }
                                        FreeMenus(menu);
                                }
                                FreeVisualInfo(vi);
                        }
                        UnlockPubScreen(NULL,sc);
                }
                if(ScreenNotifyBase && noexit)
                {
                        ReplyMsg((struct Message *)snm);
                        while(!running)
                        {
                                WaitPort(snmp);
                                if(snm=(struct ScreenNotifyMessage *)GetMsg(snmp))
                                {
                                        if(snm->snm_Value)
                                        {
                                                running=TRUE;
                                        }
                                        ReplyMsg((struct Message *)snm);
                                }
                        }
                }
        }
        
        if(ScreenNotifyBase)
        {
                if(snhandle)
                    RemWorkbenchClient(snhandle);
                if(snmp)
                    DeleteMsgPort(snmp);
                CloseLibrary(ScreenNotifyBase);
        }
        
    if(!CheckIO((struct IORequest *)tior))
        AbortIO((struct IORequest *)tior);
    WaitIO((struct IORequest *)tior);
    
        CloseDevice((struct IORequest *)tior);
        DeleteIORequest((struct IORequest *)tior);
        DeleteMsgPort(tmp);

        if(minute)
        {
                free(minute);
        }
        if(hour)
        {
                free(hour);
        }
        if(second)
        {
                free(second);
        }
        if(twelve)
        {
                free(twelve);
        }
        if(hours)
        {
                free(hours);
        }
        if(quarters)
        {
                free(quarters);
        }
        if(minutes)
        {
                free(minutes);
        }
        
        if (LocaleBase)
        {
                if(catalog)
                        CloseCatalog(catalog);
                CloseLibrary(LocaleBase);
        }

        if(*homedir)
        {
            CurrentDir(oldcd);
            UnLock(pdcd);
        }


        return rc;
}

