/*
*  XmNap  A Motif napster client
*
*  Copyright (C) 2000 Mats Peterson
*
*  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; see the file COPYING.  If not, write to
*  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
*  Boston, MA 02111-1307, USA.
*
*  Please send any comments/bug reports to
*  [email protected]  (Mats Peterson)
*/

#include <Xm/Xm.h>
#include <Xm/FileSB.h>
#include <Xm/TextF.h>
#include <Xm/Protocols.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include "main.h"
#include "msgbox.h"
#include "util.h"


#define FSB_OK      1
#define FSB_CANCEL  2

#define FSB_MODE_OPEN  0
#define FSB_MODE_SAVE  1
#define FSB_MODE_DIR   2

static String fileName = NULL;

static int mode;


static void FsBoxCB(Widget w, XtPointer clientData,
       XmFileSelectionBoxCallbackStruct *cbs)
{
   String file, dir, newFile, dflt = (String)clientData;
   int *okCancel = (int*)clientData, fd;

   switch(cbs->reason) {
       case XmCR_OK:
           if (fileName)
               XtFree(fileName);

           if (mode == FSB_MODE_DIR) {
               XmStringGetLtoR(cbs->dir, XmFONTLIST_DEFAULT_TAG,
                       &fileName);
               goto exitCB;
           }

           XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &file);
           if (*file != '/') {
               XmStringGetLtoR(cbs->dir, XmFONTLIST_DEFAULT_TAG, &dir);
               newFile = XtMalloc(strlen(dir) + 1 + strlen(file) + 1);
               sprintf(newFile, "%s/%s", dir, file);
               XtFree(dir);
               XtFree(file);
               fileName = newFile;
           } else {
               fileName = XtNewString(file);
               XtFree(file);
           }

           if (mode == FSB_MODE_SAVE) {
               if ((fd = open(fileName, O_CREAT|O_WRONLY|O_EXCL)) == -1) {
                   if (errno == EEXIST) {
                       if (! YesNoMsg("File exists, overwrite?",
                               "Cancel")) {
                           return;
                       }
                   } else {
                       ErrMsg(strerror(errno));
                       return;
                   }
               } else {
                   close(fd);
                   remove(fileName);
               }
           }
   exitCB:
           *okCancel = FSB_OK;
           break;
       case XmCR_APPLY:
           XmStringGetLtoR(cbs->dir, XmFONTLIST_DEFAULT_TAG, &dir);
           newFile = XtMalloc(strlen(dir) + 1 + strlen(dflt) + 1);
           sprintf(newFile, "%s%s", dir, dflt);
           XmTextFieldSetString(
               XmFileSelectionBoxGetChild(w, XmDIALOG_TEXT), newFile);
           XtFree(dir);
           XtFree(newFile);
           return;
       case XmCR_CANCEL:
       case XmCR_PROTOCOLS:
           *okCancel = FSB_CANCEL;
   }

   XtDestroyWidget(XtParent(w));
}


String FsBox(String name, String initDir, String dflt)
{
   Widget fsBox, parent;
   Arg args[20];
   int n;
   XmString dirString, dfltString;
   int okCancel;
   String tmp;

   parent = curFocus ? curFocus : topLevel;

   dirString = XmStringCreateLocalized(initDir);
   n = 0;
   XtSetArg (args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL);  n++;
   XtSetArg (args[n], XmNdefaultPosition, False);  n++;
   XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE);  n++;
   XtSetArg (args[n], XmNdirectory, dirString);  n++;
   fsBox = XmCreateFileSelectionDialog(parent, name, args, n);
   XmStringFree(dirString);

   if (mode != FSB_MODE_DIR) {
       tmp = (String)XtMalloc(strlen(initDir) + strlen(dflt) + 2);
       if (! strcmp(initDir, "/"))
           sprintf(tmp, "%s%s", initDir, dflt);
       else
           sprintf(tmp, "%s/%s", initDir, dflt);
       dfltString = XmStringCreateLocalized(tmp);
       XtVaSetValues(fsBox, XmNdirSpec, dfltString, NULL);
       XmStringFree(dfltString);
       XtFree(tmp);
   }

   XtUnmanageChild(XtNameToWidget(fsBox, "Help"));
   if (mode == FSB_MODE_DIR) {
       XtUnmanageChild(XtNameToWidget(fsBox, "Selection"));
       XtUnmanageChild(XtNameToWidget(fsBox, "Text"));
   }

   XtAddCallback (fsBox, XmNokCallback,
           (XtCallbackProc)FsBoxCB, (XtPointer)&okCancel);
   XtAddCallback (fsBox, XmNcancelCallback,
           (XtCallbackProc)FsBoxCB, (XtPointer)&okCancel);
   if (mode == FSB_MODE_SAVE)
       XtAddCallback (fsBox, XmNapplyCallback,
               (XtCallbackProc)FsBoxCB, (XtPointer)dflt);
   XmAddWMProtocolCallback(XtParent(fsBox),
           XmInternAtom(XtDisplay(fsBox), "WM_DELETE_WINDOW", False),
           (XtCallbackProc)FsBoxCB, (XtPointer)&okCancel);

   CenterDialog(fsBox);

   if (fileName) {
       XtFree(fileName);
       fileName = NULL;
   }

   okCancel = 0;
   while ((! okCancel) || (XtAppPending(appCon)))
       XtAppProcessEvent(appCon, XtIMAll);

   if (okCancel == FSB_OK)
       return fileName;
   else
       return "";
}


String OpenFile(String initDir, String dflt)
{
   mode = FSB_MODE_OPEN;
   return FsBox("openFile", initDir, dflt);
}


String SaveFile(String initDir, String dflt)
{
   mode = FSB_MODE_SAVE;
   return FsBox("saveFile", initDir, dflt);
}


String ChooseDir(String initDir)
{
   mode = FSB_MODE_DIR;
   return FsBox("chooseDir", initDir, NULL);
}


String ChooseSharedDir(String initDir)
{
   mode = FSB_MODE_DIR;
   return FsBox("chooseSharedDir", initDir, NULL);
}