/****************************************************************************************************************
 *
 *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
 *
 *  This program is distributed in the hope that it will be useful.
 *  Use and copying of this software and preparation of derivative works
 *  based upon this software are permitted, so long as the following
 *  conditions are met:
 *       o credit to the authors is acknowledged following current
 *         academic behaviour
 *       o no fees or compensation are charged for use, copies, or
 *         access to this software
 *       o this copyright notice is included intact.
 *  This software is made available AS IS, and no warranty is made about 
 *  the software or its performance. 
 * 
 *  Bug descriptions, use reports, comments or suggestions are welcome.
 *  Send them to    dumesnil@etca.fr   or to:
 *       
 *       Antoine de Maricourt
 *       ETCA CREA-SP
 *       16 bis, avenue Prieur de la Cote d'Or
 *       94114 Arcueil Cedex
 *       France
 */

#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>

#include <X11/cursorfont.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Label.h>

#include "xgoban.h"

/*******************************************************************************************************
 *
 */

void CenterWindow (w, button)
Widget    w;
Widget    button;
{
  Display          *display = XtDisplay (w);
  Window            root;
  Window            child;
  int               rx;
  int               ry;
  int               bw;
  int               ignore;
  unsigned int      mask;
  Arg               args[4];
  Dimension         butw;
  Dimension         buth;
  Dimension         width;
  Dimension         height;
  Position          x;
  Position          y;
  XWindowAttributes attr;

  if (XtIsRealized (w) == FALSE) XtRealizeWidget (w);

  XGetWindowAttributes (display, XtWindow (w), &attr);
  bw = attr.border_width;
  XGetWindowAttributes (display, RootWindowOfScreen (XtScreen (w)), &attr);

  XQueryPointer (display, XtWindow (w), &root, &child, &rx, &ry, &ignore, &ignore, &mask);

  XtSetArg (args[0], XtNwidth , (XtArgVal) &width );
  XtSetArg (args[1], XtNheight, (XtArgVal) &height);

  XtGetValues (w, args, 2);

  if (button != NULL) {
    XtSetArg (args[0], XtNx      , (XtArgVal) &x    );
    XtSetArg (args[1], XtNy      , (XtArgVal) &y    );
    XtSetArg (args[2], XtNwidth  , (XtArgVal) &butw );
    XtSetArg (args[3], XtNheight , (XtArgVal) &buth );

    XtGetValues (button, args, 4);

    rx = rx - x - 3 * butw / 4;
    ry = ry - y - 2 * buth / 3;
  }

  else {
    rx = rx - width  / 2;
    ry = ry - height / 2;
  }
 
  rx = (rx < 2) ? 2 : rx;
  rx = (rx > attr.width  - width  - 2 * bw - 4) ? attr.width  - width  - 2 * bw - 4 : rx;

  ry = (ry < 2) ? 2 : ry;
  ry = (ry > attr.height - height - 2 * bw - 4) ? attr.height - height - 2 * bw - 4 : ry;

  XtMoveWidget (w, rx, ry); 
}

/*******************************************************************************************************
 *
 */

void ShowCursor (node)
SG_NodePtr node;
{
  Arg            args[2];
  int            cursor = XC_question_arrow;
    
  switch (current_mode) {
    
  case EditMode      :
  case PlayMode      :
  case MailMode      :
    
    if (node != NULL) {
      
      switch (node->type) {
	
      case SG_EventType   :
      case SG_DiagramType :
	if (node->left != NULL || node->right != NULL)
	  cursor = GbCGrayStone;
	else
	  cursor = (node->player == SG_BlackStone) ? GbCBlackStone : GbCWhiteStone;
	break;
	
      case SG_MoveType :
	if (node->left != NULL || node->right != NULL)
	  cursor = GbCGrayStone;
	else
	  cursor = (node->color == SG_BlackStone) ? GbCWhiteStone : GbCBlackStone;
	break;
      }
    }

    else
      cursor =  GbCGrayStone;

    break;
    
  case SizeMode :
  case ViewMode :
    cursor =  XC_top_left_corner;
    break;
    
  case DiagramMode :
    cursor =  XC_dot;
    break;

  default :
    return;
  }
  
  XtSetArg (args[0], XtNcursor, (XtArgVal) cursor);
  XtSetValues (w_goban,  args, 1);

  if (w_second_goban != NULL)   
    XtSetValues (w_second_goban,  args, 1);
}

/*******************************************************************************************************
 *
 */

Boolean LoadFile (w, event, name)
Widget  w;
XEvent *event;
char   *name;
{
  FILE       *file;
  SG_NodePtr  node;
  char        tmp_name[1024];
  char       *src = path;
  char       *dst;

  if (*name == '/') {
    if ((file = fopen (name, "r")) == NULL)
      goto failed;
  }
  
  else 
    do {
      dst = tmp_name;
      
      while (*src != ':' && *src != '\0')
	*dst++ = *src++;
      
      if (*src == '\0' && dst == tmp_name) {
       failed :

	if (w != NULL) 
	  PopupDialog (w, event, CantOpenFileDialog);
	
	return False;
      }
      
      *dst++ = '/';
      *dst++ = '\0';
      
      if (*src == ':') src++;
      
      (void) strcat (tmp_name, name);
      file = fopen (tmp_name, "r");
      
    } while (file == NULL);

  node = SG_ReadTree (file);
  fclose (file);
  
  if (node != NULL) {
    do {
      while (node->up != NULL)
	node = node->up;
      while (node->left != NULL)
	node = node->left;
    } while (node->up != NULL);
    
    SG_FreeNode (tree);

    tree         = node;
    current_node = node;
    modified     = False;

    (void) strcpy (file_name, tmp_name); 
  }

  return True;
}

/*******************************************************************************************************
 */

Boolean SaveFile (w, event, name)
Widget  w;
XEvent *event;
char   *name;
{
  FILE       *file;
  char        tmp_name[256];
  int         saved;

  if (*name != '/')
    (void) strcpy (tmp_name, "./");

  (void) strcat (tmp_name, name);
  file = fopen (tmp_name, "w");
    
  if (file == NULL && w != NULL) {
    PopupDialog (w, event, CantOpenFileDialog);
    return False;
  }

  HideTmpProperty (current_node);
  ShowTmpProperty (current_node);

  saved = SG_WriteTree (tree, file, short_print == True ? 1 : 0);
  fclose (file);

  if (saved != 0 && w != NULL) {
    PopupDialog (w, event, CantOpenFileDialog);
    return False;
  }

  (void) strcpy (file_name, name);
  modified = False;

  return saved == 0 ? True : False;
}

/*******************************************************************************************************
 */

void Edit (flag)
Boolean flag;
{
  Arg args[4];

  if (flag == True) {
    XtSetArg (args[0], XtNeditType         , (XtArgVal) XawtextEdit        );
    XtSetArg (args[1], XtNdisplayCaret     , (XtArgVal) True               );

    XtSetValues (c_comment, args, 2);

    edit = True;
  }

  else {
    XtSetArg (args[0], XtNeditType         , (XtArgVal) XawtextRead        );
    XtSetArg (args[1], XtNdisplayCaret     , (XtArgVal) False              );

    XtSetValues (c_comment, args, 2);

    edit = False;
  }
}
