/*

Directory Opus 4
Original GPL release version 4.12
Copyright 1993-2000 Jonathan Potter

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

All users of Directory Opus 4 (including versions distributed
under the GPL) are entitled to upgrade to the latest version of
Directory Opus version 5 at a reduced price. Please see
http://www.gpsoft.com.au for more information.

The release of Directory Opus 4 under the GPL in NO WAY affects
the existing commercial status of Directory Opus 5.

*/

#include "print.h"

void get_vis_info(struct VisInfo *vis,char *portname);

void main(argc,argv)
int argc;
char *argv[];
{
    struct VisInfo vis;
    char **dummy_args,*port=NULL,*stringname;
    struct DOpusArgsList *arglist=NULL;
    BPTR oldcurdir,*dirlocks;
    int arg,printdir=0,pdwind=-1;
    struct StringData *stringdata;
    struct DOpusRemember *memkey=NULL;

    if (!(DOpusBase=(struct DOpusBase *)OpenLibrary("dopus.library",18)))
        exit(0);

    if ((dummy_args=LAllocRemember(&memkey,16*sizeof(char *),MEMF_CLEAR)) &&
        (dirlocks=LAllocRemember(&memkey,16*sizeof(BPTR),MEMF_CLEAR)) &&
        (stringname=LAllocRemember(&memkey,80,0)) &&
        (stringdata=LAllocRemember(&memkey,sizeof(struct StringData),MEMF_CLEAR))) {

        if (argc==0) {
            struct WBStartup *startup;
            int arg;

            startup=(struct WBStartup *)argv;
            for (arg=0;arg<startup->sm_NumArgs && arg<16;arg++) {
                dummy_args[arg]=startup->sm_ArgList[arg].wa_Name;
                dirlocks[arg]=startup->sm_ArgList[arg].wa_Lock;
                ++argc;
            }
            argv=dummy_args;
        }

        IntuitionBase=DOpusBase->IntuitionBase;
        GfxBase=DOpusBase->GfxBase;

        WorkbenchBase=OpenLibrary("workbench.library",0);
        PPBase=OpenLibrary("powerpacker.library",0);

        for (arg=1;arg<argc;arg++) {
            if (argv[arg][0]=='&') port=&argv[arg][1];
            else if (argv[arg][0]=='!') arglist=(struct DOpusArgsList *)atoi(&argv[arg][1]);
            else if (argv[arg][0]=='@') {
                printdir=1;
                if (argv[arg][1]=='0') pdwind=0;
                else if (argv[arg][1]=='1') pdwind=1;
            }
            else break;
        }

        get_vis_info(&vis,port);

        stringdata->default_table=default_strings;
        stringdata->string_count=STR_STRING_COUNT;
        stringdata->min_version=STRING_VERSION;

        if (vis.vi_language)
            lsprintf(stringname,"DOpus:Modules/S/DM_Print_%s.STR",vis.vi_language);
        else stringname[0]=0;

        if (ReadStringFile(stringdata,stringname)) {
            string_table=stringdata->string_table;

            if (printdir && port) do_printdir(&vis,port,pdwind);
            else {
                if (!arglist) port=NULL;
                if (dirlocks[arg]) oldcurdir=CurrentDir(dirlocks[arg]);
                do_print(&vis,port,arglist,argc-arg,&argv[arg]);
                if (dirlocks[arg]) CurrentDir(oldcurdir);
            }
        }
        FreeStringFile(stringdata);

        if (WorkbenchBase) CloseLibrary(WorkbenchBase);
        if (PPBase) CloseLibrary(PPBase);
    }
    LFreeRemember(&memkey);
    CloseLibrary((struct Library *)DOpusBase);
#ifdef __SASC_60
    __exit(0);
#else
    _exit(0);
#endif
}

void get_vis_info(vis,portname)
struct VisInfo *vis;
char *portname;
{
    vis->vi_fg=1; vis->vi_bg=0;
    vis->vi_shine=2; vis->vi_shadow=1;
    vis->vi_font=NULL;
    vis->vi_screen=NULL;
    vis->vi_stringcol[0]=1; vis->vi_stringcol[1]=0;
    vis->vi_activestringcol[0]=1; vis->vi_activestringcol[1]=0;
    vis->vi_flags=VISF_WINDOW;
    vis->vi_language=NULL;

    if (dopus_message(DOPUSMSG_GETVIS,(APTR)vis,portname)) return;

    if (IntuitionBase->LibNode.lib_Version>35) {
        struct DrawInfo *drinfo;
        struct Screen *pub;

        if (pub=LockPubScreen(NULL)) {
            drinfo=GetScreenDrawInfo(pub);
            vis->vi_shine=drinfo->dri_Pens[SHINEPEN];
            vis->vi_shadow=drinfo->dri_Pens[SHADOWPEN];
            vis->vi_fg=drinfo->dri_Pens[TEXTPEN];
            vis->vi_bg=drinfo->dri_Pens[BACKGROUNDPEN];
            FreeScreenDrawInfo(pub,drinfo);
            UnlockPubScreen(NULL,pub);
        }
    }
}

dopus_message(cmd,data,portname)
int cmd;
APTR data;
char *portname;
{
    struct MsgPort *port,*replyport;
    struct DOpusMessage msg;

    Forbid();
    if (portname && portname[0] &&
        (port=FindPort(portname)) &&
        (replyport=LCreatePort(NULL,0))) {
        msg.msg.mn_Node.ln_Type=NT_MESSAGE;
        msg.msg.mn_Node.ln_Name=NULL;
        msg.msg.mn_ReplyPort=replyport;
        msg.msg.mn_Length=(UWORD)sizeof(struct DOpusMessage);
        msg.command=cmd;
        msg.data=data;
        PutMsg(port,(struct Message *)&msg);
        Permit();
        WaitPort(replyport);
        GetMsg(replyport);
        LDeletePort(replyport);
        return(1);
    }
    Permit();
    return(0);
}

void fill_out_req(req,vis)
struct RequesterBase *req;
struct VisInfo *vis;
{
    req->rb_fg=vis->vi_fg;
    req->rb_bg=vis->vi_bg;
    req->rb_shine=vis->vi_shine;
    req->rb_shadow=vis->vi_shadow;
    req->rb_font=vis->vi_font;
    req->rb_flags&=~RBF_WINDOWCENTER;
    if (vis->vi_screen) {
        if (vis->vi_flags&VISF_WINDOW) {
            req->rb_screen=((struct Window *)vis->vi_screen)->WScreen;
            req->rb_window=(struct Window *)vis->vi_screen;
            req->rb_flags|=RBF_WINDOWCENTER;
        }
        else req->rb_screen=vis->vi_screen;
    }
    else req->rb_screen=NULL;
}

struct Gadget *addreqgadgets(reqbase,gadgets,gadgetlist)
struct RequesterBase *reqbase;
struct TagItem **gadgets;
struct Gadget **gadgetlist;
{
    int gad;
    struct Gadget *gadget=NULL,*newgadget,*firstgadget;

    for (gad=0;;gad++) {
        if (!gadgets[gad]) break;
        if (!(newgadget=(struct Gadget *)
            AddRequesterObject(reqbase,gadgets[gad]))) return(NULL);
        if (gadget) gadget->NextGadget=newgadget;
        else firstgadget=newgadget;
        gadget=newgadget;
        gadgetlist[gad]=newgadget;
    }
    AddGadgets(reqbase->rb_window,firstgadget,NULL,gad,reqbase->rb_shine,reqbase->rb_shadow,1);
    return(firstgadget);
}

void border_text(reqbase,border,infobuf)
struct RequesterBase *reqbase;
Object_Border *border;
char *infobuf;
{
    struct RastPort *rp;

    rp=reqbase->rb_window->RPort;
    SetAPen(rp,reqbase->rb_bg);
    RectFill(rp,border->ob_left,border->ob_top,
        border->ob_left+border->ob_width-1,border->ob_top+border->ob_height-1);
    SetAPen(rp,reqbase->rb_fg);

    if (infobuf) {
        ObjectText(reqbase,
            border->ob_left,
            border->ob_top,
            border->ob_width,
            border->ob_height,
            infobuf,
            TEXTPOS_CENTER);
    }
}

void set_print_env(printdata)
PrintData *printdata;
{
    int file;

    if (!(file=Open("env:DOpus_print.prefs",MODE_NEWFILE))) return;
    Write(file,(char *)printdata,sizeof(PrintData));
    Close(file);
}

void get_print_env(printdata)
PrintData *printdata;
{
    int file;

    if (!(file=Open("env:DOpus_print.prefs",MODE_OLDFILE))) return;
    Read(file,(char *)printdata,sizeof(PrintData));
    Close(file);
}

void activate_next_gadget(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
    struct Gadget *gad;
    int try;

    gad=gadget->NextGadget;
    for (try=0;try<2;try++) {
        while (gad) {
            if (gad->GadgetType==GTYP_STRGADGET && !(gad->Flags&GFLG_DISABLED)) {
                ActivateStrGad(gad,window);
                return;
            }
            gad=gad->NextGadget;
        }
        gad=window->FirstGadget;
    }
}

get_file_byrequest(gadget,window,save)
struct Gadget *gadget;
struct Window *window;
int save;
{
    struct DOpusFileReq filereq;
    char dirbuf[256],filebuf[FILEBUF_SIZE],*ptr,*path;

    path=((struct StringInfo *)gadget->SpecialInfo)->Buffer;

    filereq.title=string_table[STR_SELECT_FILE];
    filereq.dirbuf=dirbuf;
    filereq.filebuf=filebuf;
    filereq.window=window;
    filereq.x=-2;
    filereq.y=-2;
    filereq.lines=15;
    filereq.flags=(save)?DFRF_SAVE:0;
    filereq.filearraykey=NULL;
    filereq.filearray=NULL;

    strcpy(dirbuf,path);
    if ((ptr=BaseName(dirbuf))>dirbuf) {
        strcpy(filebuf,ptr);
        *ptr=0;
    }
    else if (ptr==dirbuf) {
        dirbuf[0]=0;
        strcpy(filebuf,path);
    }
    else filebuf[0]=0;

    if (!(FileRequest(&filereq)) || !filebuf[0]) return(0);

    strcpy(path,dirbuf);
    TackOn(path,filebuf,256);
    RefreshStrGad(gadget,window);
    return(1);
}

int error_rets[2]={1,0};

check_error(reqbase,str,abort)
struct RequesterBase *reqbase;
char *str;
int abort;
{
    struct DOpusSimpleRequest *req;
    char *error_gads[3];
    int ret;

    if (!(req=AllocMem(sizeof(struct DOpusSimpleRequest),MEMF_CLEAR))) return(0);
    req->text=str;
    if (abort) {
        error_gads[0]=string_table[STR_ABORT];
        error_gads[1]=string_table[STR_CONTINUE];
    }
    else {
        error_gads[0]=string_table[STR_OKAY];
        error_gads[1]=string_table[STR_CANCEL];
    }
    error_gads[2]=NULL;
    req->gads=error_gads;
    req->rets=error_rets;
    req->hi=reqbase->rb_shine;
    req->lo=reqbase->rb_shadow;
    req->fg=reqbase->rb_fg;
    req->bg=reqbase->rb_bg;
    req->font=reqbase->rb_font;
    req->flags=SRF_RECESSHI;
    if (reqbase->rb_flags&RBF_BORDERS) req->flags|=SRF_BORDERS;
    req->title="DOpus_Print";
    ret=DoSimpleRequest(reqbase->rb_window,req);
    FreeMem(req,sizeof(struct DOpusSimpleRequest));
    return(ret);
}
