/********************************************************************
This file is part of the abs 0.907 distribution.  abs is a spreadsheet
with graphical user interface.

Copyright (C) 1998-2001  André Bertin (Andre.Bertin@ping.be) 

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 if in the same spirit as version 2.

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., 675 Mass Ave, Cambridge, MA 02139, USA.

Concact: abs@pi.be
         http://home.pi.be/bertin/abs.shtml

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


























#include "param.h"
#include "memory.h"
#include "gr_interf.h"		
#include <stdio.h>

Arg w_args[50];			
int w_n;


int
w_arg (String Name, XtArgVal Value)
{
  XtSetArg (w_args[w_n], Name, Value);
  w_n++;
  return w_n;
}

int
w_set (Widget w)
{
  XtSetValues (w, w_args, w_n);
  return w_n;
}

int
w_rel (Widget w, int x, int y)
{
  XtSetArg (w_args[w_n], XtNfromHoriz, w);
  w_n++;
  XtSetArg (w_args[w_n], XtNfromVert, w);
  w_n++;
  XtSetArg (w_args[w_n], XtNhorizDistance, x);
  w_n++;
  XtSetArg (w_args[w_n], XtNvertDistance, y);
  w_n++;
  return w_n;
}

int
w_relh (Widget w, int x)
{
  XtSetArg (w_args[w_n], XtNfromHoriz, w);
  w_n++;
  XtSetArg (w_args[w_n], XtNhorizDistance, x);
  w_n++;
  return w_n;
}

int
w_relv (Widget w, int y)
{
  XtSetArg (w_args[w_n], XtNfromVert, w);
  w_n++;
  XtSetArg (w_args[w_n], XtNvertDistance, y);
  w_n++;
  return w_n;
}


int
w_dim (int x, int y)
{
  XtSetArg (w_args[w_n], XtNwidth, x);
  w_n++;
  XtSetArg (w_args[w_n], XtNheight, y);
  w_n++;
  return w_n;
}

int
w_bord (int l)
{
  XtSetArg (w_args[w_n], XtNborderWidth, l);
  w_n++;
  return w_n;
}

int
w_inbord (int l)
{
  XtSetArg (w_args[w_n], XtNinternalBorderWidth, l);
  w_n++;
  return w_n;
}

int
w_noresize ()
{
  XtSetArg (w_args[w_n], XtNleft, XtChainLeft);
  w_n++;
  XtSetArg (w_args[w_n], XtNright, XtChainLeft);
  w_n++;
  XtSetArg (w_args[w_n], XtNtop, XtChainTop);
  w_n++;
  XtSetArg (w_args[w_n], XtNbottom, XtChainTop);
  w_n++;
  
  return w_n;
}

int
w_novresize ()
{
  XtSetArg (w_args[w_n], XtNtop, XtChainTop);
  w_n++;
  XtSetArg (w_args[w_n], XtNbottom, XtChainTop);
  w_n++;
  
  return w_n;
}

int
w_novresizebot ()
{
  XtSetArg (w_args[w_n], XtNtop, XtChainBottom);
  w_n++;
  XtSetArg (w_args[w_n], XtNbottom, XtChainBottom);
  w_n++;
  
  return w_n;
}


int
w_nohresize ()
{
  XtSetArg (w_args[w_n], XtNleft, XtChainLeft);
  w_n++;
  XtSetArg (w_args[w_n], XtNright, XtChainLeft);
  w_n++;
  
  return w_n;
}

int
w_vresize ()
{
  XtSetArg (w_args[w_n], XtNtop, XtChainTop);
  w_n++;
  XtSetArg (w_args[w_n], XtNbottom, XtChainBottom);
  w_n++;
  
  return w_n;
}

int
w_hresize ()
{
  XtSetArg (w_args[w_n], XtNleft, XtChainLeft);
  w_n++;
  XtSetArg (w_args[w_n], XtNright, XtChainRight);
  w_n++;
  
  return w_n;
}

int
w_bONw ()
{
  XtSetArg (w_args[w_n], XtNbackground, abswhite);
  w_n++;
  XtSetArg (w_args[w_n], XtNforeground, absblack);
  w_n++;
  return w_n;
}




Widget
CreateLabel (Widget base, char *label, int x, int y, int w, int h)
{

  w_n = 0;
  w_dim (w, h);
  w_rel (NULL, x, y);
  XtSetArg (w_args[w_n], XtNborderWidth, 0);
  w_n++;
  XtSetArg (w_args[w_n], XtNlabel, label);
  w_n++;
  XtSetArg (w_args[w_n], XtNjustify, XtJustifyLeft);
  w_n++;
  return XtCreateManagedWidget
    (label, labelWidgetClass, base, w_args, w_n);
}

Widget
CreateText (Widget base, char *label, int x, int y, int w, int h)
{
  w_n = 0;
  w_dim (w, h);
  w_rel (NULL, x, y);
  XtSetArg (w_args[w_n], XtNborderWidth, 0);
  w_n++;
  XtSetArg (w_args[w_n], XtNjustify, XtJustifyLeft);
  w_n++;
  XtSetArg (w_args[w_n], XtNeditType, XawtextEdit);
  w_n++;
  XtSetArg (w_args[w_n], XtNscrollVertical, XawtextScrollWhenNeeded);
  w_n++;
  XtSetArg (w_args[w_n], XtNscrollHorizontal, XawtextScrollWhenNeeded);
  w_n++;
  return XtCreateManagedWidget
    (label, asciiTextWidgetClass, base, w_args, w_n);
}

void
TextPrintf (Widget w, char *str)
{
  w_n = 0;
  XtSetArg (w_args[w_n], XtNstring, str);
  w_n++;
  XtSetArg (w_args[w_n], XtNeditType, XawtextRead);
  w_n++;
  XtSetValues (w, w_args, w_n);

  XawTextDisplayCaret (w, False);

  XawTextSetInsertionPoint (w, 0);
}



static char alltextTranslations[] = "\
<Key>Home:     beginning-of-line() \n\
<Key>End:      end-of-line() \n\
<Key>Right:     forward-character() \n\
<Key>Left:      backward-character() \n\
<Key>Down:      next-line() \n\
<Key>Up:        previous-line() \n\
<Key>BackSpace: delete-previous-character() \n\
<Key>Delete:    delete-next-character() \n\
<Key>Linefeed:  newline-and-indent() \n\
<Key>Return:    newline() \n\
<Key>:          insert-char() \n\
<FocusIn>:      focus-in() \n\
<FocusOut>:     focus-out() \n\
<Btn1Down>:     select-start() \n\
<Btn1Motion>:   extend-adjust() \n\
<Btn1Up>:       extend-end(PRIMARY, CUT_BUFFER0) \n\
<Btn2Down>:     insert-selection(PRIMARY, CUT_BUFFER0) \n\
<Btn3Down>:     extend-start() \n\
<Btn3Motion>:   extend-adjust() \n\
<Btn3Up>:       extend-end(PRIMARY, CUT_BUFFER0) \n\
";

Widget
CreateEntry (Widget base, char *label, int x, int y, int w, int h, char *val)
{
  Widget ret;
  XtTranslations trans_table = XtParseTranslationTable (alltextTranslations);
  w_n = 0;
  w_dim (w, h);
  w_rel (NULL, x, y);
  XtSetArg (w_args[w_n], XtNborderWidth, 0);
  w_n++;
  XtSetArg (w_args[w_n], XtNlabel, label);
  w_n++;
  XtSetArg (w_args[w_n], XtNjustify, XtJustifyLeft);
  w_n++;
  XtSetArg (w_args[w_n], XtNstring, val);
  w_n++;
  XtSetArg (w_args[w_n], XtNinsertPosition, 1);
  w_n++;
  XtSetArg (w_args[w_n], XtNeditType, XawtextEdit);
  w_n++;
  XtSetArg (w_args[w_n], XtNtranslations, trans_table);
  w_n++;
  w_bONw ();

  ret = XtCreateManagedWidget
    (label, asciiTextWidgetClass, base, w_args, w_n);
  return ret;
}

int 
EntrySetEditable (Widget w, int yes)
{
  w_n = 0;
  if (yes)
    {
      XtSetArg (w_args[w_n], XtNeditType, XawtextEdit);
      w_n++;
      XawTextDisplayCaret (w, True);
    }
  else
    {
      XtSetArg (w_args[w_n], XtNeditType, XawtextRead);
      w_n++;
      XawTextDisplayCaret (w, False);
    }
  w_set (w);
  return 0;
}

int 
EntrySetInsertionPosition (Widget w, int pos)
{
  w_n = 0;
  XtSetArg (w_args[w_n], XtNinsertPosition, pos);
  w_set (w);
  return 0;
}


int
SetEntryString (Widget w, char *buf)
{
  w_n = 0;
  XtSetArg (w_args[w_n], XtNstring, buf);
  w_n++;
  XtSetValues (w, w_args, w_n);
  return 0;
}

char *
GetEntryString (Widget w)
{
  char *buf;

  w_n = 0;
  XtSetArg (w_args[w_n], XtNstring, &buf);
  w_n++;
  XtGetValues (w, w_args, w_n);

  return buf;
}


int
SetEntryVal (Widget w, double val)
{
  char buf[256];
  sprintf (buf, "%g", val);
  w_n = 0;
  XtSetArg (w_args[w_n], XtNstring, buf);
  w_n++;
  XtSetValues (w, w_args, w_n);
  return 0;
}

double
GetEntryVal (Widget w)
{
  char *buf;
  double val;

  w_n = 0;
  XtSetArg (w_args[w_n], XtNstring, &buf);
  w_n++;
  XtGetValues (w, w_args, w_n);

  sscanf (buf, "%lf", &val);

  return val;
}



int
insertstring (Widget w, char *str)
{
  XawTextBlock text;
  long p = XawTextGetInsertionPoint (w);
  text.firstPos = 0;
  text.length = strlen (str);
  text.ptr = str;
  XawTextReplace (w, p, p, &text);
  XawTextSetInsertionPoint (w, p + text.length);


  return 0;
}

int
moveinsertionpoint (Widget w, int delta)
{
  int len;
  XawTextPosition p;
  char *str = GetEntryString (w);
  if (str == NULL)
    return -1;
  len = strlen (str);
  p = XawTextGetInsertionPoint (w);
  if (p + delta >= len && p + delta < 0)
    return -2;

  XawTextSetInsertionPoint (w, p + delta);
  return 0;
}

int
EntryDelChr (Widget t)
{
  long p;
  int l, i;
  char *str;
  char *tmp;

  str = GetEntryString (t);
  if (str == NULL)
    return -1;

  l = strlen (str);
  if (l <= 0)
    return -2;
  tmp = (char *) absmalloc (sizeof (char) * l + 1, "EntryString_delete:tmp");
  strcpy (tmp, str);

  p = XawTextGetInsertionPoint (t);
  if (p == l)
    return -3;

  for (i = p; i < l - 1; i++)
    tmp[i] = tmp[i + 1];
  tmp[l - 1] = '\0';

  SetEntryString (t, tmp);
  XawTextSetInsertionPoint (t, p);

  return 0;
}

int
EntryBackChr (Widget t)
{
  long p;
  int l, i;
  char *str;
  char *tmp;

  str = GetEntryString (t);
  if (str == NULL)
    return -1;

  l = strlen (str);
  if (l <= 0)
    return -2;
  tmp = (char *) absmalloc (sizeof (char) * l + 1, "EntryString_delete:tmp");
  strcpy (tmp, str);

  p = XawTextGetInsertionPoint (t);
  if (p <= 0)
    return -3;

  for (i = p - 1; i < l - 1; i++)
    tmp[i] = tmp[i + 1];
  tmp[l - 1] = '\0';

  SetEntryString (t, tmp);
  XawTextSetInsertionPoint (t, p - 1);

  return 0;
}






void
shadow (Widget widget, XtPointer pointer, XEvent * event, Boolean * ctd)
{
  int n;
  Dimension h, w;
  Widget wi;
  Arg args[2];			
  wi = (Widget) pointer;

  n = 0;
  XtSetArg (args[n], XtNheight, &h);
  n++;
  XtSetArg (args[n], XtNwidth, &w);
  n++;
  XtGetValues (wi, args, n);
  w--;
  h--;
  desactivate_zoom ();
  drawline (XtDisplay (wi), XtWindow (wi), 0, 0, 0, w, 0, 0, 0);
  drawline (XtDisplay (wi), XtWindow (wi), 3, w, 0, w, h, 0, 0);
  drawline (XtDisplay (wi), XtWindow (wi), 3, w, h, 0, h, 0, 0);
  drawline (XtDisplay (wi), XtWindow (wi), 0, 0, h, 0, 0, 0, 0);
  reactivate_zoom ();

}

void
shadow2 (Widget widget, XtPointer pointer, XEvent * event, Boolean * ctd)
{
  int n;
  Dimension h, w;
  Widget wi;
  Arg args[2];			
  wi = (Widget) pointer;

  n = 0;
  XtSetArg (args[n], XtNheight, &h);
  n++;
  XtSetArg (args[n], XtNwidth, &w);
  n++;
  XtGetValues (wi, args, n);
  w--;
  h--;
  desactivate_zoom ();
  drawline (XtDisplay (wi), XtWindow (wi), 3, 0, 0, w, 0, 0, 0);
  drawline (XtDisplay (wi), XtWindow (wi), 0, w, 0, w, h, 0, 0);
  drawline (XtDisplay (wi), XtWindow (wi), 0, w, h, 0, h, 0, 0);
  drawline (XtDisplay (wi), XtWindow (wi), 3, 0, h, 0, 0, 0, 0);
  reactivate_zoom ();

}

void
shadow3 (Widget widget, XtPointer pointer, XEvent * event, Boolean * ctd)
{
  int n;
  Dimension h, w;
  Position x, y;
  Widget wi, parent;
  Arg args[4];			
  wi = (Widget) pointer;
  parent = XtParent (wi);
  n = 0;
  XtSetArg (args[n], XtNx, &x);
  n++;
  XtSetArg (args[n], XtNy, &y);
  n++;
  XtSetArg (args[n], XtNheight, &h);
  n++;
  XtSetArg (args[n], XtNwidth, &w);
  n++;
  XtGetValues (wi, args, n);
  desactivate_zoom ();
  drawline (XtDisplay (parent), XtWindow (parent), 3, x - 1, y - 1, x - 1, y + h + 1, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 0, x - 1, y + h + 1, x + w + 1, y + h + 1, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 0, x + w + 1, y + h + 1, x + w + 1, y - 1, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 3, x + w + 1, y - 1, x - 1, y - 1, 0, 0);
  reactivate_zoom ();
}

void
shadow4 (Widget widget, XtPointer pointer, XEvent * event, Boolean * ctd)
{
  int n;
  Dimension h, w;
  Position x, y;
  Widget wi, parent;
  Arg args[4];			
  wi = (Widget) pointer;
  parent = XtParent (wi);
  n = 0;
  XtSetArg (args[n], XtNx, &x);
  n++;
  XtSetArg (args[n], XtNy, &y);
  n++;
  XtSetArg (args[n], XtNheight, &h);
  n++;
  XtSetArg (args[n], XtNwidth, &w);
  n++;
  XtGetValues (wi, args, n);
  desactivate_zoom ();
  drawline (XtDisplay (parent), XtWindow (parent), 0, x - 1, y - 1, x - 1, y + h + 1, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 3, x - 1, y + h + 1, x + w + 1, y + h + 1, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 3, x + w + 1, y + h + 1, x + w + 1, y - 1, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 0, x + w + 1, y - 1, x - 1, y - 1, 0, 0);
  reactivate_zoom ();
}

void
shadow5 (Widget widget, XtPointer pointer, XEvent * event, Boolean * ctd)
{
  int n;
  Dimension h, w;
  Position x, y;
  Widget wi, parent;
  Arg args[4];			
  wi = (Widget) pointer;
  parent = XtParent (wi);
  n = 0;
  XtSetArg (args[n], XtNx, &x);
  n++;
  XtSetArg (args[n], XtNy, &y);
  n++;
  XtSetArg (args[n], XtNheight, &h);
  n++;
  XtSetArg (args[n], XtNwidth, &w);
  n++;
  XtGetValues (wi, args, n);
  desactivate_zoom ();
  drawline (XtDisplay (parent), XtWindow (parent), 0, x + 3, y + 3, x + 3, y + h - 3, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 3, x + 3, y + 3, x + w - 3, y + 3, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 0, x + w - 3, y + 3, x + 3, y + 3, 0, 0);
  reactivate_zoom ();
}

void
shadow6 (Widget widget, XtPointer pointer, XEvent * event, Boolean * ctd)
{
  int n;
  Dimension h, w;
  Position x, y;
  Widget wi, parent;
  Arg args[4];			
  wi = (Widget) pointer;
  parent = XtParent (wi);
  n = 0;
  XtSetArg (args[n], XtNx, &x);
  n++;
  XtSetArg (args[n], XtNy, &y);
  n++;
  XtSetArg (args[n], XtNheight, &h);
  n++;
  XtSetArg (args[n], XtNwidth, &w);
  n++;
  XtGetValues (wi, args, n);
  desactivate_zoom ();
  drawline (XtDisplay (parent), XtWindow (parent), 3, x - 2, y - 2, x - 2, y + h + 2, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 0, x - 2, y + h + 2, x + w + 1, y + h + 2, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 0, x + w + 2, y + h + 2, x + w + 2, y - 2, 0, 0);
  drawline (XtDisplay (parent), XtWindow (parent), 3, x + w + 2, y - 2, x - 2, y - 2, 0, 0);
  reactivate_zoom ();
}



int
addshadow (Widget w, int type)
{
  switch (type)
    {
    case 1:
      XtAddEventHandler (w,
			 ExposureMask,
			 FALSE,
			 shadow,
			 (caddr_t) w);


      break;

    case 2:
      XtAddEventHandler (w,
			 ExposureMask,
			 FALSE,
			 shadow2,
			 (caddr_t) w);
      break;
    case 3:
      XtAddEventHandler (w,
      
			 VisibilityChangeMask,
			 FALSE,
			 shadow3,
			 (caddr_t) w);
      break;
    case 4:
      {
	XtAddEventHandler (w,
			   ExposureMask,
			   FALSE,
			   shadow4,
			   (caddr_t) w);
      }
      break;
    case 5:
      XtAddEventHandler (w,
			 PointerMotionMask,
			 FALSE,
			 shadow5,
			 (caddr_t) w);
      break;
    case 6:
      XtAddEventHandler (w,
			 VisibilityChangeMask,
			 TRUE,
			 shadow6,
			 (caddr_t) w);



      break;

    }
  return 0;
}

static char scrollTranslations[] =
"<Btn1Down>:   StartScroll(Continuous) MoveThumb() NotifyThumb() \n\
     <Btn2Down>:   StartScroll(Continuous) MoveThumb() NotifyThumb() \n\
     <Btn3Down>:   StartScroll(Continuous) MoveThumb() NotifyThumb() \n\
     <Btn1Motion>: MoveThumb() NotifyThumb() \n\
     <Btn2Motion>: MoveThumb() NotifyThumb() \n\
     <Btn3Motion>: MoveThumb() NotifyThumb() \n\
     <BtnUp>:      NotifyScroll(Proportional) EndScroll()";


#include <X11/cursorfont.h>

int
modscroll (Widget w)
{
  XtTranslations trans_table;

  trans_table = XtParseTranslationTable (scrollTranslations);
  XtOverrideTranslations (w, trans_table);

  w_n = 0;
  w_bONw ();
  w_arg (XtNthumb, None);




  w_set (w);
  return 0;
}
