/*********************************************************************/
/*  bibView: Administration of BibTeX-Databases                      */
/*           (Verwaltung von BibTeX-Literaturdatenbanken)            */
/*                                                                   */
/*  Module:  gui_edit.c                                              */
/*                                                                   */
/*             GUI Edit Window                                       */
/*                                                                   */
/*  Author:  Holger Martin,  martinh@informatik.tu-muenchen.de       */
/*           Peter M. Urban, urban@informatik.tu-muenchen.de         */
/*                                                                   */
/*  History:                                                         */
/*    05.03.92  PMU  created                                         */
/*    05.26.92       Version 1.0 released                            */
/*                                                                   */
/*  Copyright 1992 TU MUENCHEN                                       */
/*    See ./Copyright for complete rights and liability information. */
/*                                                                   */
/*********************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/Text.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/SmeLine.h>
#include "bibview.h"


/* imported global variables */
/* ------------------------- */
extern Widget topLevel, desktop;
extern Pixmap macIconPixmap;


/* macros and definitions */
/* ---------------------- */


/* local function prototypes */
/* ------------------------- */


/* exported variables */
/* ------------------ */


/* local global variables */
/* ---------------------- */
void gueSetEditChangeFlag (Widget w, XtPointer clientData, XtPointer callData);
void gueSaveBibErrWinCmd (Widget w, XtPointer clientData, XtPointer callData);



/*********************************************************************/
/* gueOpenMacroWin:                                                  */
/*    Opens shell for editing macros of a bibliography               */
/*********************************************************************/
Errcode
gueOpenMacroWin (BibPtr bp)
{
MacroWinPtr mw;

   /* allocate memory for new element of window list */
   if ((mw = (MacroWinPtr) XtMalloc(sizeof(MacroWin))) == NULL) {
      /* error-handling is done in control modules */
      return(ERR_NOMALLOC);
   }

   /* allocate memory for label of new shell */
   if ((mw->shellName = 
      (String) XtCalloc(strlen(PROGNAME)+strlen(bp->filename)+12, 
		      sizeof(char))) == NULL) {
      return(ERR_NOMALLOC);
   }

   bp->mw = mw;
   sprintf(mw->shellName, "%s: Macros %s", PROGNAME, bp->filename);
   mw->changed = FALSE;

   /* position window and icon */
   gueSetWindowCoords(bp, TRUE);
   if (cotIconizeOnDesktop())
      gueSetIconCoords(bp, TRUE);

   /* create popup shell for new file */
   mw->macShell = XtVaCreatePopupShell("macShell",
		  topLevelShellWidgetClass, topLevel, 
                  XtNx, mw->winX,
		  XtNy, mw->winY, 
                  XtNiconX, mw->iconX,
		  XtNiconY, mw->iconY, 
		  XtNtitle, mw->shellName, 
		  XtNiconPixmap, macIconPixmap,
		  XtNiconName, bp->filename, NULL);
   mw->macWin = XtVaCreateManagedWidget("macWin",
		  panedWidgetClass, mw->macShell, NULL);

   /* create command buttons */
   mw->cmdBox = XtVaCreateManagedWidget("commandBox", 
		  boxWidgetClass, mw->macWin, NULL);
   mw->save   = XtVaCreateManagedWidget("save", 
	          commandWidgetClass, mw->cmdBox, NULL);
   mw->close  = XtVaCreateManagedWidget("close", 
	          commandWidgetClass, mw->cmdBox, NULL);
   mw->file   = XtVaCreateManagedWidget("macText", 
	          asciiTextWidgetClass, mw->macWin, 
		  XtNtype, XawAsciiFile,
		  XtNeditType, XawtextEdit,
		  XtNstring, bp->macrofile,
		  XtNscrollHorizontal, XawtextScrollWhenNeeded,
		  XtNscrollVertical, XawtextScrollWhenNeeded, NULL);

   XtAddCallback(mw->close, XtNcallback, cseQuitMacrosCmd, (XtPointer)bp);
   XtAddCallback(mw->save, XtNcallback, cseSaveMacrosCmd, (XtPointer)bp);
   XtAddCallback(XawTextGetSource(mw->file), 
		 XtNcallback, cseSetMacroChangeFlag, (XtPointer)bp);
   XtPopup(mw->macShell, XtGrabNone);
   return(OK);
}


/*********************************************************************/
/* gueMacroWinExists:                                                */
/*    TRUE, if macro window exists, else FALSE                       */
/*********************************************************************/
Boolean
gueMacroWinExists (BibPtr bp)
{
   return(bp->mw != NULL);
}


/*********************************************************************/
/* gueCloseMacroWinCmd:                                              */
/*    Callback function for macro window button close                */
/*********************************************************************/
void
gueCloseMacroWinCmd (Widget w, XtPointer clientData, XtPointer callData)
{
BibPtr bp = (BibPtr) clientData;
Errcode status;

   if ((status = gueCloseMacroWin(bp)) != OK)
      guwError(status);
}


/*********************************************************************/
/* gueCloseMacroWin:                                                 */
/*    Close macro window                                             */
/*********************************************************************/
Errcode
gueCloseMacroWin (BibPtr bp)
{
   if (bp->mw != NULL) {
      XtPopdown(bp->mw->macShell);
      XtFree((char *)bp->mw->shellName);
      XtFree((char *)bp->mw);
      bp->mw = NULL; 
   }
   return(OK);
}


/*********************************************************************/
/* gueSaveMacrosToFile:                                              */
/*    Save macros to file                                            */
/*********************************************************************/
Errcode
gueSaveMacrosToFile (BibPtr bp)
{
   if (bp->mw != NULL) {
      if (!XawAsciiSave(XawTextGetSource(bp->mw->file)))
	 return(ERR_SAVING_TMP);
      bp->mw->changed = FALSE;
   }
   bp->changed = TRUE;
   return(OK);
}


/*********************************************************************/
/* gueCascade:                                                       */
/*    Reposition macro window                                        */
/*********************************************************************/
Errcode
gueCascade (BibPtr bp)
{
   if (bp->mw == NULL) /* is list window open? */
      return(OK);

   gueSetWindowCoords(bp, FALSE);
   if (cotIconizeOnDesktop())
      gueSetIconCoords(bp, FALSE);
   return(OK);
}


/*********************************************************************/
/* gueSetWindowCoords:                                               */
/*    Set position of macro window                                   */
/*********************************************************************/
Errcode
gueSetWindowCoords (BibPtr bp, Boolean calcOnly)
{
Dimension dwidth, dheight;
Position x, y;
MacroWinPtr mw = bp->mw;

   if (mw == NULL) /* is list window open? */
      return(OK);

   /* calculate position of window */
   XtVaGetValues(bp->bw->bibdesk,
		 XtNwidth, &dwidth,
		 XtNheight, &dheight, NULL);
   x = dwidth - SUBWIN_MARGIN;
   y = SUBWIN_MARGIN;
   XtTranslateCoords(bp->bw->bibdesk,
		     x, y,
		     &mw->winX, &mw->winY);

   /* set values */
   if (!calcOnly) {
      XtVaSetValues(mw->macShell,
                    XtNx, mw->winX,
		    XtNy, mw->winY, NULL);
      if (XtIsRealized(mw->macShell)) {
         XRaiseWindow(XtDisplay(mw->macShell),
		      XtWindow(mw->macShell));
      }
   }
   return(OK);
}


/*********************************************************************/
/* gueSetIconCoords:                                                 */
/*    Set position of macro window icon                              */
/*********************************************************************/
Errcode
gueSetIconCoords (BibPtr bp, Boolean calcOnly)
{
Dimension dwidth, dheight;
Position x, y;
MacroWinPtr mw = bp->mw;

   if (mw == NULL) /* is list window open? */
      return(OK);

   /* calculate position of icon */
   XtVaGetValues(bp->bw->bibdesk,
		 XtNwidth, &dwidth,
		 XtNheight, &dheight, NULL);
   x = dwidth - (2 * (LST_ICON_WIDTH + LST_ICON_MARGIN));
   y = LST_ICON_MARGIN;
   XtTranslateCoords(bp->bw->bibdesk,
	             x, y, 
		     &mw->iconX, &mw->iconY);

   /* set values */
   if (!calcOnly) {
      XtVaSetValues(mw->macShell,
		    XtNiconX, mw->iconX,
		    XtNiconY, mw->iconY, NULL);
   }
   return(OK);
}


/*********************************************************************/
/* gueUnsetIconCoords:                                               */
/*    Delete position of macro window icon                           */
/*********************************************************************/
Errcode
gueUnsetIconCoords (BibPtr bp, Boolean calcOnly)
{
MacroWinPtr mw = bp->mw;

   if (mw == NULL) /* is list window open? */
      return(OK);

   mw->iconX = mw->iconY = -1;
   if (!calcOnly) {
      XtVaSetValues(mw->macShell,
		    XtNiconX, mw->iconX,
		    XtNiconY, mw->iconY, NULL);
   }
   return(OK);
}

/*********************************************************************/
/* gueErrorWinExists:                                                */
/*    TRUE, if error window exists, else FALSE                       */
/*********************************************************************/
Boolean
gueErrorWinExists (BibPtr bp)
{
   return(bp->ew != NULL);
}


/*********************************************************************/
/* gueOpenBibErrWin:                                                 */
/*    Opens shell for editing  errors of a bibliography              */
/*********************************************************************/
Errcode
gueOpenBibErrWin (BibPtr bp, int line)
{
MacroWinPtr mw;
	
   if (gueErrorWinExists(bp)) {
      if (XtIsRealized(bp->ew->macShell)) {
	 XRaiseWindow(XtDisplay(bp->ew->macShell),
		      XtWindow(bp->ew->macShell));
      }
      return(OK);
   }

   if (access(bp->filepath, R_OK) != 0)
      return(ERR_NO_OPEN_FILE);

   if (access(bp->filepath, W_OK) != 0)
      return(ERR_NO_OPEN_FILE);

   /* allocate memory for new element of window list */
   if ((mw = (MacroWinPtr) XtMalloc(sizeof(MacroWin))) == NULL) {
      /* error-handling is done in control modules */
      return(ERR_NOMALLOC);
   }

   /* allocate memory for label of new shell */
   if ((mw->shellName = 
      (String) XtCalloc(strlen(PROGNAME)+strlen(bp->filename)+12, 
		      sizeof(char))) == NULL) {
      return(ERR_NOMALLOC);
   }

   bp->ew = mw;
   bp->ew->changed = FALSE;
   sprintf(mw->shellName, "%s: Errors %s", PROGNAME, bp->filename);
   gueSetWindowCoords(bp, TRUE);
   if (cotIconizeOnDesktop())
      gueSetIconCoords(bp, TRUE);

   mw->macShell = XtVaCreatePopupShell("macShell",
		  topLevelShellWidgetClass, topLevel, 
                  XtNwidth, 400,
		  XtNheight, 500, 
		  XtNtitle, mw->shellName, 
		  XtNiconPixmap, macIconPixmap,
		  XtNiconName, bp->filename, NULL);
   mw->macWin = XtVaCreateManagedWidget("macWin",
		  panedWidgetClass, mw->macShell, NULL);
   mw->cmdBox = XtVaCreateManagedWidget("commandBox", 
		  boxWidgetClass, mw->macWin, NULL);
   mw->save   = XtVaCreateManagedWidget("save", 
	          commandWidgetClass, mw->cmdBox, NULL);
   mw->close  = XtVaCreateManagedWidget("close", 
	          commandWidgetClass, mw->cmdBox, NULL);
   mw->file   = XtVaCreateManagedWidget("macText", 
	          asciiTextWidgetClass, mw->macWin, 
		  XtNtype, XawAsciiFile,
		  XtNstring, bp->filepath, 
		  XtNdataCompression, False,
		  XtNeditType, XawtextEdit, 
		  XtNscrollHorizontal, XawtextScrollWhenNeeded,
		  XtNscrollVertical, XawtextScrollWhenNeeded, NULL);

   XtAddCallback(mw->close, XtNcallback, gueCloseBibErrWinCmd, (XtPointer)bp);
   XtAddCallback(mw->save, XtNcallback, gueSaveBibErrWinCmd, (XtPointer)bp);
   XtAddCallback(XawTextGetSource(mw->file), 
		 XtNcallback, gueSetEditChangeFlag, (XtPointer)bp);
   XtPopup(mw->macShell, XtGrabNone); 
   XawTextSetInsertionPoint(mw->file, 0);
   return(OK);
}



/*********************************************************************/
/* gueCloseBibErrWinCmd:                                             */
/*    Callback function for error window button close                */
/*********************************************************************/
void
gueCloseBibErrWinCmd (Widget w, XtPointer clientData, XtPointer callData)
{
BibPtr bp = (BibPtr) clientData;
Errcode status;
   if ((status = gueCloseBibErrWin(bp)) != OK)
      guwError(status);
}


/*********************************************************************/
/* gueCloseBibErrWin:                                                */
/*    Close error window                                             */
/*********************************************************************/
Errcode
gueCloseBibErrWin (BibPtr bp)
{  
   if (bp->ew != NULL) {
      XtPopdown(bp->ew->macShell);
      XtDestroyWidget(bp->ew->macShell);
      XtDestroyWidget(bp->ew->macWin);
      XtDestroyWidget(bp->ew->cmdBox);
      XtDestroyWidget(bp->ew->save);
      XtDestroyWidget(bp->ew->close);
      XtDestroyWidget(bp->ew->file);
      XtFree((char *)bp->ew->shellName);
      XtFree((char *)bp->ew); 
      bp->ew = NULL; 
   }
   return(OK);
}


/*********************************************************************/
/* gueSaveBibErrWinCmd:                                              */
/*    Callback function for error window button save                 */
/*********************************************************************/
void
gueSaveBibErrWinCmd (Widget w, XtPointer clientData, XtPointer callData)
{
BibPtr bp = (BibPtr) clientData;
Errcode status;

   if ((status = gueSaveBibErrWin(bp)) != OK)
     {guwError(status);
      return;
      }
   if (bp->ew != NULL) {
      XtDestroyWidget(bp->ew->macShell);
      XtDestroyWidget(bp->ew->macWin);
      XtDestroyWidget(bp->ew->cmdBox);
      XtDestroyWidget(bp->ew->save);
      XtDestroyWidget(bp->ew->close);
      XtDestroyWidget(bp->ew->file);
      XtFree((char *)bp->ew->shellName);
      XtFree((char *)bp->ew); 
      bp->ew = NULL; 
   }
   return;
}


/*********************************************************************/
/* gueSaveBibErrWin:                                                 */
/*    Save  error window                                             */
/*********************************************************************/
Errcode
gueSaveBibErrWin (BibPtr bp)
{
   if (bp->ew != NULL) {
      if (XawAsciiSave(XawTextGetSource(bp->ew->file)) == FALSE) 
	 return(ERR_SAVING_TMP); 
      bp->ew->changed = FALSE; 
   }

   return(OK);
}


/*********************************************************************/
/* gueSetEditChangeFlag:                                             */
/*    Callback of text widget, sets flags when buffer changes        */
/*********************************************************************/
void
gueSetEditChangeFlag (Widget w, XtPointer clientData, XtPointer callData)
{
BibPtr bp = (BibPtr)clientData;

   bp->ew->changed = TRUE;
}

