/********************************************************************
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 <stdio.h>
#include <sys/stat.h>
#include <string.h>

#include "style.h"
#include "cell.h"
#include "cell_vb.h"		
#include "worksheet.h"
#include "draw.h"
#include "graph.h"
#include "range.h"
#include "application.h"
#include "y.tab.h"
#include "info_dialog.h"
#include "memory.h"
#include "main.h"
#include "callback.h"
#include "newplot.h"
#include "fig.h"
#include "gr_interf.h"
#include "clipboard.h"

static int copy_incr = 1;
static int high = 0;
static int sj;
static int si;
static int lj, li;
static int brushing = 0;

#define AW ActiveWorksheet

int
incr ()
{
  scanf ("%d", &copy_incr);
  return 0;
}

static Cell *brushref = NULL;

int
setbrush (Cell * cell)
{
  brushref = cell;
  brushing = 1;
  return 0;
}

int
makebrush (int i1, int j1, int i2, int j2)
{
  int i, j;
  if (!brushing)
    return 0;
  brushing = 0;
  if (brushref == NULL)
    return -1;
  if (ActiveWorksheet == NULL)
    return -1;

  if (i1 < 1 || j1 < 1 || i2 > ActiveWorksheet->nblin || j2 > ActiveWorksheet->nbcol)
    {
      return -1;
    }

  for (i = i1; i <= i2; i++)
    for (j = j1; j <= j2; j++)
      cell_stycpy ((Cell *) applicationcell (i, j, 1), brushref);
  brushref = NULL;
  return 0;
}


int
makesorta ()
{
  int i, j;

  Cell **tosort;
  int k = 0;
  char buf[256];
  int istext = 0;

  if (ActiveWorksheet == NULL)
    return -1;

  if (si < 1 || sj < 1 || li > ActiveWorksheet->nblin || lj > ActiveWorksheet->nbcol)
    {
      return -1;
    }

  tosort = (Cell **) absmalloc (sizeof (Cell *) * (lj - sj + 1) * (li - si + 1), "makesorta:tosort");
  k = 0;


  for (i = si; i <= li; i++)
    for (j = sj; j <= lj; j++)
      {
	tosort[k] = (Cell *) applicationcell (i, j, 1);
	if (tosort[k] != NULL)
	  {
	    if (cell_istext (tosort[k]))
	      istext = 1;
	  }
	k++;
      }


  if (k < 2)
    {
      absfree (tosort, "makesortd:tosort");
      return 0;
    }

  if (istext)
    for (i = 0; i < k; i++)
      {
	for (j = i + 1; j < k; j++)
	  {
	    if (cell_gettext (tosort[i]) != NULL && cell_gettext (tosort[j]) != NULL)
	      if (strcmp (cell_gettext (tosort[i]), cell_gettext (tosort[j])) > 0)
		{
		  if (cell_getformula (tosort[i]) != NULL)
		    strcpy (buf, cell_getformula (tosort[i]));
		  else
		    buf[0] = '\0';
		  cell_setformula (tosort[i], cell_getformula (tosort[j]));
		  cell_setformula (tosort[j], buf);
		}
	  }
      }
  else
    for (i = 0; i < k; i++)
      {
	for (j = i + 1; j < k; j++)
	  {
	    if (cell_getvalue (tosort[i]) > cell_getvalue (tosort[j]))
	      {
		if (cell_getformula (tosort[i]) != NULL)
		  strcpy (buf, cell_getformula (tosort[i]));
		else
		  buf[0] = '\0';
		cell_setformula (tosort[i], cell_getformula (tosort[j]));
		cell_setformula (tosort[j], buf);
	      }

	  }
      }

  absfree (tosort, "makesortd:tosort");
  xrepaint ("makesortd");
  return 0;
}
int
makesortd ()
{
  int i, j;

  Cell **tosort;
  int k = 0;
  char buf[256];
  int istext = 0;

  if (ActiveWorksheet == NULL)
    return -1;

  if (si < 1 || sj < 1 || li > ActiveWorksheet->nblin || lj > ActiveWorksheet->nbcol)
    {
      return -1;
    }

  tosort = (Cell **) absmalloc (sizeof (Cell *) * (lj - sj + 1) * (li - si + 1), "makesorta:tosort");
  k = 0;


  for (i = si; i <= li; i++)
    for (j = sj; j <= lj; j++)
      {
	tosort[k] = (Cell *) applicationcell (i, j, -1);
	if (tosort[k] != NULL)
	  {
	    if (cell_istext (tosort[k]))
	      istext = 1;
	  }
	k++;
      }

  if (k < 2)
    {
      absfree (tosort, "makesorta:tosort");
      return 0;
    }

  if (istext)
    for (i = 0; i < k; i++)
      {
	for (j = i + 1; j < k; j++)
	  {
	    if (cell_gettext (tosort[i]) != NULL && cell_gettext (tosort[j]) != NULL)
	      if (strcmp (cell_gettext (tosort[i]), cell_gettext (tosort[j])) < 0)
		{
		  if (cell_getformula (tosort[i]) != NULL)
		    strcpy (buf, cell_getformula (tosort[i]));
		  else
		    buf[0] = '\0';
		  cell_setformula (tosort[i], cell_getformula (tosort[j]));
		  cell_setformula (tosort[j], buf);
		}
	  }
      }
  else
    for (i = 0; i < k; i++)
      {
	for (j = i + 1; j < k; j++)
	  {
	    if (cell_getvalue (tosort[i]) < cell_getvalue (tosort[j]))
	      {
		if (cell_getformula (tosort[i]) != NULL)
		  strcpy (buf, cell_getformula (tosort[i]));
		else
		  buf[0] = '\0';
		cell_setformula (tosort[i], cell_getformula (tosort[j]));
		cell_setformula (tosort[j], buf);
	      }

	  }
      }
  absfree (tosort, "makesorta:tosort");
  xrepaint ("makesorta");
  return 0;
}

int
insertfile (char *filename, int icomma, int itab, int ispace, int idotcom, int other, int asone, char *o)
{
  int i, j;
  FILE *fp = NULL;		
  char line[1024];
  char word[1024];
  int cp = 0;
  int pos = 0;
  int sep = 0;
  int curi = 1;
  int curj = 1;

  i = 1;
  j = 1;

  fp = fopen (filename, "r");
  if (fp == NULL)
    return -1;

  word[0] = '\0';

  while (fgets (line, 1020, fp) != NULL)
    {
      pos = 0;
      cp = 0;
      while (line[pos] != '\0' && pos < 1020)
	{
	  if (asone)
	    {
	      while (((line[pos] == ',' && icomma) ||
		      (line[pos] == '	' && itab) ||
		      (line[pos] == ' ' && ispace) ||
		      (line[pos] == '\n') ||
		      (line[pos] == EOF) ||
		      (line[pos] == ';' && idotcom)
		     ) && line[pos] != '\0' && pos < 1020
		)
		{
		  sep = 1;
		  pos++;
		}
	      if (sep)
		j++;
	    }
	  else
	    {
	      if (line[pos] == ',' && icomma)
		{
		  j++;
		  sep = 1;
		  pos++;
		}
	      if (line[pos] == '	' && itab)
		{
		  j++;
		  sep = 1;
		  pos++;
		}
	      if (line[pos] == ' ' && ispace)
		{
		  j++;
		  sep = 1;
		  pos++;
		}
	      if (line[pos] == ';' && idotcom)
		{
		  j++;
		  sep = 1;
		  pos++;
		}
	      if (line[pos] == '\n')
		{
		  j++;
		  sep = 1;
		  pos++;
		}
	      if (line[pos] == EOF)
		{
		  j++;
		  sep = 1;
		  pos++;
		}
	    }

	  if (sep)
	    {
	      word[cp] = '\0';
	      if (strlen (word) > 0)
		set_formula (curi + i - 1, curj + j - 2, word);
	      sep = 0;
	      cp = 0;
	    }
	  else
	    {
	      word[cp] = line[pos];
	      pos++;
	      cp++;
	    }
	}
      j = 1;
      i++;
    }
  fclose (fp);
  return 0;
}

void
exportfile (char *filename, int icomma, int itab, int ispace, int idotcom, int other, int asone, char *o)
{
  int i, j;
  FILE *fp = NULL;		

  if (ActiveWorksheet == NULL)
    return;

  if (si < 1 || sj < 1 || li > ActiveWorksheet->nblin || lj > ActiveWorksheet->nbcol)
    {
      si = 1;
      sj = 1;
      li = ActiveWorksheet->maxrow;
      lj = 0;
      for (i = 0; i < ActiveWorksheet->maxrow; i++)
	{
	  if (ActiveWorksheet->maxcol[i] > lj)
	    lj = ActiveWorksheet->maxcol[i];
	}
    }

  fp = fopen (filename, "w");
  if (fp == NULL)
    return;
  {
    for (i = si; i <= li; i++)
      {
	if (i > si)
	  fprintf (fp, "\n");
	for (j = sj; j <= lj; j++)
	  {
	    if (j > sj)
	      {
		if (itab)
		  fprintf (fp, "    ");
		if (icomma)
		  fprintf (fp, ",");
		if (ispace)
		  fprintf (fp, " ");
		if (idotcom)
		  fprintf (fp, ";");
	      }
	    if (get_text (i, j) != NULL)
	      fprintf (fp, "%s", get_text (i, j));
	    else
	      fprintf (fp, "0");
	  }
      }
  }
  fclose (fp);

}


void
m_exit ()
{
  if (Ask ("Really quit?", NULL) == RET_OK)
    exit (0);
}

int
copy ()
{
  if (ActiveWorksheet == NULL)
    return -1;
  if (ActiveWorksheet->selection == NULL)
    return -1;

  copy_clipboard (ActiveWorksheet->selection);
  return 0;
}

int
paste ()
{

  if (ActiveWorksheet == NULL)
    return -1;
  if (ActiveWorksheet->selection == NULL)
    return -1;
  paste_clipboard (ActiveWorksheet->selection);
  return 0;

}

int 
paste_special (int all, int formula, int value, int format, int none, int add, int sub, int div, int mul, int trans)
{

  if (ActiveWorksheet == NULL)
    return -1;
  if (ActiveWorksheet->selection == NULL)
    return -1;
  paste_special_clipboard (ActiveWorksheet->selection, all, formula, value, format, none, add, sub, div, mul, trans);
  return 0;

}



int
cut ()
{
  if (ActiveWorksheet == NULL)
    return -1;
  if (ActiveWorksheet->selection == NULL)
    return -1;
  cut_clipboard (ActiveWorksheet->selection);

  return 0;
}

int
makeformat (int type, int decimal)
{
  int i, j;
  Cell *cell;

  if (type < 1 || type > 5)
    return -1;

  

  if (sj > 0 && si > 0 && lj <= ActiveWorksheet->nbcol && li <= ActiveWorksheet->nblin)
    for (i = 0; i <= lj - sj; i++)
      {
	for (j = 0; j <= li - si; j++)
	  {
	    cell = (Cell *) applicationcell (si + j, sj + i, 1);
	    cell_setformat (cell, type, decimal);
	    xdrawcell2 (cell, 4, 1);
	  }
      }
  else
    {
      if (ActiveCell != NULL)
	{
	  cell_setformat (ActiveCell, type, decimal);
	  xdrawcell2 (ActiveCell, 4, 1);
	}
    }
  copypix ("makeformat");
  return 0;
}

int
makejust (int just)
{

  Cell *cell;

  
  cell = worksheet_selection_cells (ActiveWorksheet);
  while (cell != NULL)
    {
      cell_setjust (cell, just);
      xdrawcell2 (cell, 4, 1);
      cell = worksheet_selection_cells (ActiveWorksheet);
    }

  copypix ("makejust");
  return 0;
}

int
makefont (int fontnum, int fontweight, int fontsize)
{
  int i, j;
  Cell *cell;

  

  if (sj > 0 && si > 0 && lj <= ActiveWorksheet->nbcol && li <= ActiveWorksheet->nblin)
    for (i = 0; i <= lj - sj; i++)
      {
	for (j = 0; j <= li - si; j++)
	  {
	    cell = (Cell *) applicationcell (si + j, sj + i, 1);
	    cell_setfont (cell, fontnum, fontweight, fontsize);
	    xdrawcell2 (cell, 4, 1);
	  }
      }
  else
    {
      if (ActiveCell != NULL)
	{
	  cell_setfont (ActiveCell, fontnum, fontweight, fontsize);
	  xdrawcell2 (ActiveCell, 4, 1);
	}
    }

  copypix ("makefont");
  return 0;
}



int
border (int border, int type)
{
  int i, j;
  Cell *cell;

  if (sj > 0 && si > 0 && lj <= ActiveWorksheet->nbcol && li <= ActiveWorksheet->nblin)
    {
      switch (border)
	{
	case 8:		
	  {
	    for (j = 0; j <= lj - sj; j++)
	      {
		cell = (Cell *) applicationcell (si, sj + j, 1);
		cell_setborders (cell, border, type);
		xdrawcell2 (cell, 4, 1);
	      }
	    break;
	  }
	case 9:		
	  {
	    for (j = 0; j <= lj - sj; j++)
	      {
		
		
		
		cell = (Cell *) applicationcell (li + 1, sj + j, 1);
		cell_setborders (cell, 8, type);
		xdrawcell2 (cell, 4, 1);
	      }
	    break;
	  }
	case 10:		
	  {
	    for (i = 0; i <= li - si; i++)
	      {
		
		
		
		cell = (Cell *) applicationcell (si + i, lj + 1, 1);
		cell_setborders (cell, 7, type);
		xdrawcell2 (cell, 4, 1);
	      }
	    break;
	  }
	case 7:		
	  {
	    for (i = 0; i <= li - si; i++)
	      {
		cell = (Cell *) applicationcell (si + i, sj, 1);
		cell_setborders (cell, border, type);
		xdrawcell2 (cell, 4, 1);
	      }
	    break;
	  }
	case 1:		
	  {
	    for (j = 1; j <= lj - sj; j++)
	      {
		for (i = 0; i <= li - si; i++)
		  {
		    cell = (Cell *) applicationcell (si + i, sj + j, 1);
		    cell_setborders (cell, 7, type);
		    xdrawcell2 (cell, 4, 1);
		  }
	      }
	    break;
	  }
	case 2:		
	  {

	    for (j = 0; j <= lj - sj; j++)
	      {
		for (i = 1; i <= li - si; i++)
		  {
		    cell = (Cell *) applicationcell (si + i, sj + j, 1);
		    cell_setborders (cell, 8, type);
		    xdrawcell2 (cell, 4, 1);
		  }
	      }

	    break;
	  }


	}
    }
  else
    {
      if (ActiveCell != NULL)
	{
	  cell_setborders (ActiveCell, border, type);
	  xdrawcell2 (ActiveCell, 4, 1);
	}
    }
  copypix ("border");
  return 0;
}

int
fit ()
{
  int i, j;

  

  if (sj > 0 && si > 0 && lj <= ActiveWorksheet->nbcol && li <= ActiveWorksheet->nblin)
    for (i = 0; i <= lj - sj; i++)
      {
	for (j = 0; j <= li - si; j++)
	  {
	    xfit (si + j, sj + i);
	  }
      }
  return 0;
}

void
formatcolumn ()
{
  int i, j;

  

  if (sj > 0 && si > 0 && lj <= ActiveWorksheet->nbcol && li <= ActiveWorksheet->nblin)
    for (i = 0; i <= lj - sj; i++)
      {
	for (j = 0; j <= li - si; j++)
	  {
	    xfitcolumn (si + j, sj + i);
	  }
      }
  xrepaint ("format column");
  return;
}

void
formatline ()
{
  int i, j;

  

  if (sj > 0 && si > 0 && lj <= ActiveWorksheet->nbcol && li <= ActiveWorksheet->nblin)
    for (i = 0; i <= lj - sj; i++)
      {
	for (j = 0; j <= li - si; j++)
	  {
	    xfitline (si + j, sj + i);
	  }
      }
  xrepaint ("format line");
  return;
}



int
color ()
{
  makecolor (1, 0);
  return 0;
}

int
makecolor (int fg, int bg)
{
  int i, j;
  Cell *cell;

  
  if (sj > 0 && si > 0 && lj <= ActiveWorksheet->nbcol && li <= ActiveWorksheet->nblin)
    for (i = 0; i <= lj - sj; i++)
      {
	for (j = 0; j <= li - si; j++)
	  {
	    cell = (Cell *) applicationcell (si + j, sj + i, 1);
	    cell_setfg (cell, fg);
	    cell_setbg (cell, bg);
	    xdrawcell2 (cell, 4, 1);
	  }
      }
  else
    {
      if (ActiveCell != NULL)
	{
	  cell_setfg (ActiveCell, fg);
	  cell_setbg (ActiveCell, bg);
	  xdrawcell2 (ActiveCell, 4, 1);
	}
    }

  copypix ("makecolor");
  return 0;
}


int
copyd ()
{
  int i, j;


  for (i = 0; i <= lj - sj; i++)
    {
      for (j = 1; j <= li - si; j++)
	{			
	  copymod (si, sj + i, si + j, sj + i, copy_incr);
	}
    }
  for (j = 0; j <= lj - sj; j++)
    {
      for (i = 0; i <= li - si; i++)
	{
	  xdrawcell (si + i, sj + j, 4, 1);
	}
    }

  copypix ("copyd");
  return 0;
}

int
copyr ()
{
  int i, j;

  for (i = 1; i <= lj - sj; i++)
    {
      for (j = 0; j <= li - si; j++)
	{			
	  copymod (si + j, sj, si + j, sj + i, copy_incr);
	}
    }

  for (j = 0; j <= lj - sj; j++)
    {
      for (i = 0; i <= li - si; i++)
	{
	  xdrawcell (si + i, sj + j, 4, 1);
	}
    }

  copypix ("copyr");
  return 0;
}

void
m_auditcell ()
{
  cell_auditcell (ActiveCell);
};


int
insertline ()
{
  int i, j;

  int nbrow = ActiveWorksheet->maxrow;
  int r = ActiveCell->r;
  Cell *backup = ActiveCell;

  if (ActiveCell == NULL)
    return -1;
  if (ActiveWorksheet == NULL)
    return -1;
  if (r < 1 || r > nbrow)
    return -2;

  setsi (r);

  for (i = nbrow; i > r; i--)
    {
      for (j = 1; j <= ActiveWorksheet->maxcol[i]; j++)
	{			
	  copymod (i, j, i + 1, j, 1);
	}
    }
  for (j = 1; j <= ActiveWorksheet->maxcol[r + 1]; j++)
    {				
      clear_cell (applicationcell (r + 1, j, 1));
    }

  for (i = nbrow + 1; i > r; i--)
    {
      for (j = 1; j <= ActiveWorksheet->maxcol[i]; j++)
	{
	  xdrawcell (i, j, 4, 1);
	}
    }

  setsi (-1);
  ActiveCell = backup;
  copypix ("insertline");
  return 0;
}

int
insertcolumn ()
{
  int i, j;

  int nbrow = ActiveWorksheet->maxrow;
  int c = ActiveCell->c;
  int nbcol;
  int maxcol = 0;
  Cell *backup = ActiveCell;

  if (ActiveCell == NULL)
    return -1;
  if (ActiveWorksheet == NULL)
    return -1;

  for (i = 1; i <= nbrow; i++)
    {
      nbcol = ActiveWorksheet->maxcol[i];
      if (nbcol > maxcol)
	maxcol = nbcol;
    }

  if (c < 1 || c > maxcol)
    return -2;


  setsj (c);



  for (i = 1; i <= nbrow; i++)
    {
      nbcol = ActiveWorksheet->maxcol[i];
      for (j = nbcol; j > c; j--)
	{			
	  copymod (i, j, i, j + 1, 1);
	}
    }
  for (i = 1; i <= nbrow; i++)
    {				
      clear_cell (applicationcell (i, c + 1, 1));
    }

  for (i = 1; i <= nbrow; i++)
    {
      nbcol = ActiveWorksheet->maxcol[i];
      for (j = nbcol; j > c; j--)
	{
	  xdrawcell (i, j, 4, 1);
	}
    }

  setsj (-1);
  ActiveCell = backup;
  copypix ("insertcolumn");
  return 0;
}

int
delline ()
{
  int i, j;

  int nbrow = ActiveWorksheet->maxrow;
  int r = ActiveCell->r;
  Cell *backup = ActiveCell;

  if (ActiveCell == NULL)
    return -1;
  if (ActiveWorksheet == NULL)
    return -1;
  if (r < 1 || r > nbrow)
    return -2;

  setsi (r - 1);

  for (i = r; i < nbrow; i++)
    {
      for (j = 1; j <= ActiveWorksheet->maxcol[i]; j++)
	{			
	  copymod (i + 1, j, i, j, 1);
	}
    }
  for (j = 1; j <= ActiveWorksheet->maxcol[nbrow]; j++)
    {				
      clear_cell (applicationcell (nbrow, j, 1));
    }

  for (i = r; i <= nbrow; i++)
    {
      for (j = 1; j <= ActiveWorksheet->maxcol[i]; j++)
	{
	  xdrawcell (i, j, 4, 1);
	}
    }

  setsi (-1);
  ActiveCell = backup;
  copypix ("delline");
  return 0;
}

int
delcolumn ()
{
  int i, j;

  int nbrow = ActiveWorksheet->maxrow;
  int c = ActiveCell->c;
  int nbcol;
  int maxcol = 0;
  Cell *backup = ActiveCell;

  if (ActiveCell == NULL)
    return -1;
  if (ActiveWorksheet == NULL)
    return -1;

  for (i = 1; i <= nbrow; i++)
    {
      nbcol = ActiveWorksheet->maxcol[i];
      if (nbcol > maxcol)
	maxcol = nbcol;
    }

  if (c < 1 || c > maxcol)
    return -2;


  setsj (c - 1);



  for (i = 1; i <= nbrow; i++)
    {
      nbcol = ActiveWorksheet->maxcol[i];
      for (j = c; j < nbcol; j++)
	{			
	  copymod (i, j + 1, i, j, 1);
	}
    }
  for (i = 1; i <= nbrow; i++)
    {
      nbcol = ActiveWorksheet->maxcol[i];
      if (nbcol > 0)
	clear_cell (applicationcell (i, nbcol, 1));
    }

  for (i = 1; i <= nbrow; i++)
    {
      nbcol = ActiveWorksheet->maxcol[i];
      for (j = c; j <= nbcol; j++)
	{
	  xdrawcell (i, j, 4, 1);
	}
    }

  setsj (-1);
  ActiveCell = backup;
  copypix ("delcolumn");
  return 0;
}



int
resetselect (int ii, int jj, int k)
{
  char label[2];
  sprintf (label, " ");
  inform (label);
  worksheet_select_cell (ActiveWorksheet, ActiveCell);
  
  if (ii == 0 && jj == 0 && k == 0)
    {
      si = li = 0;
      sj = lj = 0;
      high = 0;
      selectingto0 ();
      copypix ("resetselect 1");
      return 0;
    }
  if (ii >= si && ii <= li && jj >= sj && jj <= lj && !k)
    return -1;

  
  si = li = 0;
  sj = lj = 0;
  high = 0;
  selectingto0 ();
  copypix ("resetselect 2");
  return 0;
}

int
extendselection (int i, int j)
{
  int i1, i2, j1, j2;
  getselection (&i1, &j1, &i2, &j2);

  if (i < i1)
    {
      i1 = i;
    }
  else
    {
      i2 = i;
    }
  if (j < j1)
    {
      j1 = j;
    }
  else
    {
      j2 = j;
    }


  if (i1 == 0 || j1 == 0)
    {
      if (ActiveCell == NULL)
	{
	  return -1;
	}
      else
	{
	  i1 = ActiveCell->r;
	  j1 = ActiveCell->c;
	}
    }
  return setselection (i1, j1, i2, j2);
}

int
setselection (int i1, int j1, int i2, int j2)
{
  int t;
  char label[16];

  worksheet_select_range (ActiveWorksheet, i1, j1, i2, j2);

  if (i1 > i2)
    {
      t = i1;
      i1 = i2;
      i2 = t;
    }
  if (j1 > j2)
    {
      t = j1;
      j1 = j2;
      j2 = t;
    }

  si = i1;
  sj = j1;
  li = i2;
  lj = j2;

  if (i1 != i2 || j1 != j2)
    {
      high = 1;

      sprintf (label, "%d L x %d C\n", li - si + 1, lj - sj + 1);
      inform (label);
    }
  return 0;
}

int
setselectionrange (Range * range)
{
  if (range == NULL)
    return 1;
  if (range->nplage < 1)
    return 2;

  return setselection (range->plage[0].r1, range->plage[0].c1, range->plage[0].r2, range->plage[0].c2);

}

int
getselection (int *i1, int *j1, int *i2, int *j2)
{
  *i1 = si;
  *i2 = li;
  *j1 = sj;
  *j2 = lj;
  return 0;
}



int
selectlin (int lin, int shift)
{
  char label[16];






  sj = 1;
  lj = ActiveWorksheet->nbcol - 1;
  if (shift)
    {
      if (lin <= si)
	si = lin;
      else
	li = lin;
    }
  else
    {
      si = li = lin;
    }
  high = 1;
  worksheet_select_range (ActiveWorksheet, si, sj, li, lj);
  sprintf (label, "%d L x %d C\n", li - si + 1, lj - sj + 1);
  inform (label);


  return 0;
}

int
selectcol (int col, int shift)
{
  char label[16];






  si = 1;
  li = ActiveWorksheet->nblin - 1;
  if (shift)
    {
      if (sj <= col)
	sj = col;
      else
	lj = col;
    }
  else
    {
      sj = lj = col;
    }
  high = 1;
  worksheet_select_range (ActiveWorksheet, si, sj, li, lj);
  sprintf (label, "%d L x %d C\n", li - si + 1, lj - sj + 1);
  inform (label);

  return 0;
}

int
selectall ()
{
  char label[64];
  si = 1;

  sj = 1;

  li = ActiveWorksheet->nblin;
  lj = ActiveWorksheet->nbcol;
  high = 1;
  worksheet_select_range (ActiveWorksheet, si, sj, li, lj);
  sprintf (label, "%d L x %d C\n", li - si + 1, lj - sj + 1);
  inform (label);
  return 0;
}



int
selection (int ii, int jj)
{
  char label[16];

  if (lj == jj && li == ii)
    return 0;
  if (high == 0)
    {
      sj = lj = jj;
      si = li = ii;
    }
  lj = jj;
  li = ii;
  high = 1;


  worksheet_select_range (ActiveWorksheet, si, sj, li, lj);

  sprintf (label, "%d L x %d C\n", li - si + 1, lj - sj + 1);
  inform (label);

  copypix ("selection");
  return 0;

}

int
moveselect (int fri, int frj, int toi, int toj, int k)
{
  int i, j;
  Cell *cell1;
  Cell *cell2;

  if (toi < 1)
    toi = 1;
  if (toj < 1)
    toj = 1;

  


  if (si + toi - fri < 1 || sj + toj - frj < 1
      || li + toi - fri > AW->nblin - 1
      || lj + toj - frj > AW->nbcol - 1)
    return 0;


  if (k)
    {
      if (si == 0 && sj == 0 && ActiveCell != NULL)
	{
	  cell2 = ActiveCell;
	  cell1 = (Cell *) applicationcell (ActiveCell->r + toi - fri, ActiveCell->c + toj - frj, 1);
	  copymod3 (cell1, cell2, 1);
	  cell_stycpy (cell1, cell2);
	  clear_cell (cell2);
	  xdrawcell2 (cell2, 4, 1);
	  xdrawcell2 (cell1, 4, 1);
	  return 0;
	}
      
      if (toi - fri >= 0 && toj - frj >= 0)
	{
	  for (i = li; i >= si; i--)
	    {
	      for (j = lj; j >= sj; j--)
		{
		  cell2 = (Cell *) applicationcell (i, j, 1);
		  cell1 = (Cell *) applicationcell (i + toi - fri, j + toj - frj, 1);
		  copymod3 (cell1, cell2, 1);
		  cell_stycpy (cell1, cell2);
		  clear_cell (cell2);
		  xdrawcell2 (cell2, 4, 1);
		  xdrawcell2 (cell1, 4, 1);
		}
	    }
	}
      else if (toi - fri <= 0 && toj - frj >= 0)
	{
	  for (i = si; i <= li; i++)
	    {
	      for (j = lj; j >= sj; j--)
		{
		  cell2 = (Cell *) applicationcell (i, j, 1);
		  cell1 = (Cell *) applicationcell (i + toi - fri, j + toj - frj, 1);
		  copymod3 (cell1, cell2, 1);
		  cell_stycpy (cell1, cell2);
		  clear_cell (cell2);
		  xdrawcell2 (cell2, 4, 1);
		  xdrawcell2 (cell1, 4, 1);
		}
	    }
	}
      else if (toi - fri >= 0 && toj - frj <= 0)
	{
	  for (i = li; i >= si; i--)
	    {
	      for (j = sj; j <= lj; j++)
		{
		  cell2 = (Cell *) applicationcell (i, j, 1);
		  cell1 = (Cell *) applicationcell (i + toi - fri, j + toj - frj, 1);
		  copymod3 (cell1, cell2, 1);
		  
		  cell_stycpy (cell1, cell2);
		  clear_cell (cell2);
		  xdrawcell2 (cell2, 4, 1);
		  xdrawcell2 (cell1, 4, 1);
		}
	    }


	}
      else if (toi - fri <= 0 && toj - frj <= 0)
	{
	  for (i = si; i <= li; i++)
	    {
	      for (j = sj; j <= lj; j++)
		{
		  cell2 = (Cell *) applicationcell (i, j, 1);
		  cell1 = (Cell *) applicationcell (i + toi - fri, j + toj - frj, 1);
		  copymod3 (cell1, cell2, 1);
		  
		  cell_stycpy (cell1, cell2);
		  clear_cell (cell2);
		  xdrawcell2 (cell2, 4, 1);
		  xdrawcell2 (cell1, 4, 1);
		}
	    }
	}

      si += toi - fri;
      li += toi - fri;
      sj += toj - frj;
      lj += toj - frj;
      copypix ("moveselect 1");
    }
  else
    {
      si += toi - fri;
      li += toi - fri;
      sj += toj - frj;
      lj += toj - frj;
      copypix ("moveselect 2");
      si -= toi - fri;
      li -= toi - fri;
      sj -= toj - frj;
      lj -= toj - frj;

    }

  setselection (si, sj, li, lj);

  return 0;
}

int
myfprintf (FILE * fp, char *word, int l)
{
  int i;
  if (strcmp (word, "\n") == 0)
    return -1;
  for (i = 0; i <= l - strcspn (word, " "); i++)
    fprintf (fp, " ");
  fprintf (fp, "%s", word);
  return 0;
}



























int
printplot (int number)
{
  return 0;
}

int
is_selecting ()
{
  return high;
}

int
get_select (int *i1, int *j1, int *i2, int *j2)
{
  *i1 = si;
  *i2 = li;
  *j1 = sj;
  *j2 = lj;
  return high;
}





void
updategraph ()
{
  plot (0);
}

int
alphatonum (char *buf, int *ii, int *jj)
{				
				
  int len;
  int i;
  int c = 0;
  int r = 0;
  int pos = 0;

  len = strlen (buf);

  for (i = 0; i < len; i++)
    {
      if ('a' <= buf[i] && buf[i] <= 'z')
	buf[i] = 'A' + buf[i] - 'a';
    }

  if (buf[0] == '$')
    {
      pos++;
    }

  while ('A' <= buf[pos] && buf[pos] <= 'Z')
    {
      c *= 26;
      c += (buf[pos] - 'A' + 1);
      pos++;
    }

  if (buf[pos] == '$')
    {
      pos++;
    }
  sscanf (buf + pos, "%d", &r);

  *ii = r;
  *jj = c;

  return 0;
}

static char *ALPHA[] =
{
  "A", "B", "C", "D", "E", "F", "G", "H", "I",
  "J", "K", "L", "M", "N", "O", "P", "Q", "R",
  "S", "T", "U", "V", "W", "X", "Y", "Z",
  NULL};


int
numtoalpha (char *buf, int j, int i)
{				
				
  buf[0] = '\0';
  if (i > 26 * 26)
    return -1;
  if (i > 26)
    {
      sprintf (buf, "%s%s", buf, ALPHA[(i - 1) / 26 - 1]);
      i = i - 26 * ((i - 1) / 26);
    }
  if (i < 1)
    i = 1;
  sprintf (buf, "%s%s", buf, ALPHA[i - 1]);
  sprintf (buf, "%s%d", buf, j);


  return 0;
}
int
numtoalpha2 (char *buf, int j, int i, int dj, int di)
{				
				
  buf[0] = '\0';
  if (di)
    sprintf (buf, "$");
  if (i > 26 * 26)
    return -1;
  if (i > 26)
    {
      sprintf (buf, "%s%s", buf, ALPHA[(i - 1) / 26 - 1]);
      i = i - 26 * ((i - 1) / 26);
    }
  if (i < 1)
    i = 1;
  sprintf (buf, "%s%s", buf, ALPHA[i - 1]);
  if (dj)
    sprintf (buf, "%s$", buf);
  sprintf (buf, "%s%d", buf, j);


  return 0;
}

int
coltoalpha (char *buf, int i)
{				
				
  buf[0] = '\0';
  if (i > 26 * 26)
    return -1;
  if (i > 26)
    {
      sprintf (buf, "%s%s", buf, ALPHA[(i - 1) / 26 - 1]);
      i = i - 26 * ((i - 1) / 26);
    }
  if (i < 1)
    i = 1;
  sprintf (buf, "%s%s", buf, ALPHA[i - 1]);


  return 0;
}
