/********************************************************************
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 "application.h"
#include "symboltable.h"
#include "memory.h"
#include "main.h"
#include "info_dialog.h"
#include "clipboard.h"


#define MAX_WORKBOOK 50

static Drawing *clipboarddrawing = NULL;
static Button *clipboardbutton = NULL;

static Workbook *workbooks[MAX_WORKBOOK];
static int nbdoc = 0;
static int totnbdoc = 0;

int
application_quit ()
{
  m_exit ();
  freeclipboard (clipboard);
  return 0;
}
int
application_calculate ()
{
  int i;
  for (i = 0; i < nbdoc; i++)
    workbook_calculate (workbooks[i]);
  return 0;
}
int 
application_nbwb ()
{
  return nbdoc;
}



Workbook *
application_getworkbook (int i)
{
  if (i < 0 || i >= MAX_WORKBOOK)
    {
      fprintf (stderr, "app_getwork: Maximum number of workbooks is %d\n", MAX_WORKBOOK);
      i = 0;
    }

  if (i < nbdoc)
    return workbooks[i];
  else
    fprintf (stderr, "app_getwork: Asking for non existing workbooks %d\n", i);
  return workbooks[0];
}

Workbook *
application_addworkbook (filename)
     char *filename;
{
  return new_doc (filename);
}

extern int add_window_name (char *name);
extern int remove_window_name (char *name);

Workbook *
new_doc (filename)
     char *filename;
{
  char name[16];

  if (filename == NULL)
    {
      sprintf (name, "Document%d", totnbdoc + 1);
      filename = name;
    }

  if (nbdoc < MAX_WORKBOOK)
    {
      workbooks[nbdoc] = newworkbook (filename);
      activate_doc (nbdoc);
      nbdoc++;
      totnbdoc++;
      add_window_name (filename);
      return workbooks[nbdoc - 1];
    }
  else
    fprintf (stderr, "new_doc: Maximum number of workbooks is %d\n", MAX_WORKBOOK);
  return workbooks[0];
}

int
close_doc ()
{
  int i = 0;
  int j;
  Workbook *tofree;

  if (nbdoc == 1)
    return 1;

  while (i < nbdoc && ActiveWorkbook != workbooks[i])
    i++;
  if (i == nbdoc)
    return 0;

  remove_window_name (ActiveWorkbook->name);
  tofree = ActiveWorkbook;

  for (j = i; j < nbdoc - 1; j++)
    workbooks[j] = workbooks[j + 1];
  workbooks[nbdoc] = NULL;
  nbdoc--;

  
  activate_doc (nbdoc - 1);


  freeworkbook (tofree);

  return 0;
}

extern int resetselect (int i, int j, int k);
extern int xrepaint (char *message);

int
activate_doc (int n)
{

  ActivateWorkbook (workbooks[n]);
  resetselect (0, 0, 0);
  xrepaint ("activate_doc");
  return 0;
  
  
  
  

}


int
application_changesheet (sheet)
     int sheet;
{
  if (ActiveWorkbook->activeworksheet == ActiveWorkbook->Worksheets[sheet])
    return -1;

  ActiveWorkbook->activeworksheet = ActiveWorkbook->Worksheets[sheet];
  ActivateWorksheet (ActiveWorkbook->Worksheets[sheet]);
  return 0;
}




int
Activate_workbook2 (filename)
     char *filename;
{
  int i = 0;
  if (filename == NULL)
    return -1;
  if (strlen (filename) < 1)
    return -2;

  while (i < nbdoc && strcmp (filename, workbooks[i]->name))
    i++;
  if (i < nbdoc)
    ActivateWorkbook (workbooks[i]);
  xrepaint ("activate_workbook2");
  return 0;
}

void
openfile (filename)
     char *filename;
{
  Workbook *wb;

  if (filename == NULL)
    return;
  if (strlen (filename) < 1)
    return;

  wb = application_addworkbook (filename);

  project_addmodule (wb->project, filename);
  
  gotolabel ("main");



}

void
savefile ()
{
  workbook_save (ActiveWorkbook, ActiveWorkbook->name);
}

void
saveasfile (filename)
     char *filename;
{
  if (filename == NULL)
    return;
  if (strlen (filename) < 1)
    return;

  remove_window_name (ActiveWorkbook->name);
  add_window_name (filename);

  workbook_save (ActiveWorkbook, filename);
}


int
init_application ()
{
  clipboard = newclipboard ();
  new_doc ("Document1");
  return 0;
}


Cell *
applicationcell (i, j, new)
     int i, j, new;
{
  
  
  
  
  if (i < 0 || i > NB_LINE)
    i = 1;
  if (j < 0 || j > NB_COLUMN)
    j = 1;
  if (ActiveWorksheet == NULL)
    return NULL;
  return worksheet_getcell (ActiveWorksheet, i, j, new);
}

Cell *
applicationwkscell (char *wksname, int i, int j, int new)
{
  Worksheet *wks;

  wks = workbook_getsheet (ActiveWorkbook, wksname);
  if (wks == NULL)
    wks = ActiveWorksheet;
  if (i < 0 || i > NB_LINE)
    i = 1;
  if (j < 0 || j > NB_COLUMN)
    j = 1;
  return worksheet_getcell (wks, i, j, new);
}



char *
get_text (i, j)
     int i, j;
{
  return cell_gettext (applicationcell (i, j, -1));
  return NULL;
}

double
get_value (i, j)
     int i, j;
{
  Cell *cell = applicationcell (i, j, -1);
  return ((cell != NULL) ? cell_getvalue (cell) : 0.0);
}

double
get_value_wks (wks, i, j)
     Worksheet *wks;
     int i, j;
{
  Cell *cell = worksheet_getcell (wks, i, j, -1);
  return ((cell != NULL) ? cell_getvalue (cell) : 0.0);
}

obj
get_ovalue (i, j)
     int i, j;
{
  obj o;
  Cell *cell = applicationcell (i, j, -1);
  o.type = 0;
  return ((cell != NULL) ? cell->val : o);
}

obj
get_ovalue_wks (wks, i, j)
     Worksheet *wks;
     int i, j;
{
  obj o;
  Cell *cell = worksheet_getcell (wks, i, j, -1);
  o.type = 0;
  return ((cell != NULL) ? cell->val : o);
}



int
set_value (i, j, x)
     int i, j;
     double x;
{
  Cell *c;


  
  c = applicationcell (i, j, 1);
  cell_setvalue (c, x);

  return 1;
}

int
set_formula (i, j, buf)
     int i, j;
     char *buf;
{
  Cell *c;
  c = (applicationcell (i, j, 1));
  
  cell_setformula (c, buf);
  return 0;
  
}

int
set_text (i, j, buf)
     int i, j;
     char *buf;
{
  Cell *c;
  c = (applicationcell (i, j, 1));
  
  cell_settext (c, buf);
  return 0;
  
}

char *
get_formula (i, j)
     int i, j;
{
  return cell_getformula (applicationcell (i, j, 0));
}

int
set_fg (i, j, f)
     int i, j, f;
{
  return cell_setfg (applicationcell (i, j, 1), f);
}

int
get_fg (i, j)
     int i, j;
{
  return cell_getfg (applicationcell (i, j, 0));
}

int
set_bg (i, j, f)
     int i, j, f;
{
  return cell_setbg (applicationcell (i, j, 1), f);
}

int
get_bg (i, j)
     int i, j;
{
  return cell_getbg (applicationcell (i, j, 0));
}

int
set_format (i, j, f, l)
     int i, j, f, l;
{
  return cell_setformat (applicationcell (i, j, 1), f, l);
}

int
get_format (i, j, f, l)
     int i, j;
     int *f, *l;
{
  return cell_getformat (applicationcell (i, j, 0), f, l);
}

int
set_border (i, j, f)
     int i, j, f;
{
  return cell_setborder (applicationcell (i, j, 1), f);
}

int
get_border (i, j)
     int i, j;
{
  return cell_getborder (applicationcell (i, j, 0));
}

int
set_just (i, j, f)
     int i, j, f;
{
  return cell_setjust (applicationcell (i, j, 1), f);
}

int
get_just (i, j)
     int i, j;
{
  return cell_getjust (applicationcell (i, j, 0));
}

int
set_font (i, j, f, g, h)
     int i, j, f, g, h;
{
  return cell_setfont (applicationcell (i, j, 1), f, g, h);
}

int
get_font (i, j)
     int i, j;
{
  return cell_getfont (applicationcell (i, j, 0));
}

int
get_fonts (i, j)
     int i, j;
{
  return cell_getfonts (applicationcell (i, j, 0));
}

int
get_fontw (i, j)
     int i, j;
{
  return cell_getfontw (applicationcell (i, j, 0));
}














































































































































Graph *
newgra ()
{
  Graph *activegra = worksheet_newgraph (ActiveWorksheet);
  ActivateGraph (activegra);
  return activegra;
}

Graph *
getlastgra ()
{
  return ActiveGraph;
}

int
getnumgra ()
{
  return ActiveWorksheet->nbgraph;
}

int
setactivegra (n)
     int n;
{
  ActivateGraph (ActiveWorksheet->Graphs[n]);
  return 0;
}

Graph *
getgra (n)
{
  return ActiveWorksheet->Graphs[n];
}

int
getactivegra ()
{
  int i;
  for (i = 0; i < getnumgra (); i++)
    if (ActiveGraph == getgra (i))
      return i;
  return 0;
}

void
getrange (int serie, char *buf, char *name)
{
  Graph *gr;
  char i1j1[20];
  char i2j2[20];
  int j;
  if (ActiveGraph == NULL)
    return;
  gr = ActiveGraph;
  j = serie - 1;
  if (serie > gr->numrange)
    {
      sprintf (buf, " ");
      sprintf (name, " ");
    }
  else
    {
      numtoalpha (i1j1, (gr->range[j]).i1, (gr->range[j]).j1);
      numtoalpha (i2j2, (gr->range[j]).i2, (gr->range[j]).j2);
      sprintf (buf, "%s:%s", i1j1, i2j2);
      strcpy (name, gr->range[j].name);
    }
  return;
}

void
deleterange (int serie)
{
  Graph *gr;
  int i, j;

  if (ActiveGraph == NULL)
    return;

  gr = ActiveGraph;
  j = serie - 1;
  if (serie > gr->numrange || j < 1)
    return;

  for (i = j; i < gr->numrange - 1; i++)
    {
      strcpy (gr->range[i].name, gr->range[i + 1].name);
      gr->range[i].i1 = gr->range[i + 1].i1;
      gr->range[i].i2 = gr->range[i + 1].i2;
      gr->range[i].j1 = gr->range[i + 1].j1;
      gr->range[i].j2 = gr->range[i + 1].j2;
    }
  strcpy (gr->range[i].name, " ");
  gr->range[i].i1 = 0;
  gr->range[i].i2 = 0;
  gr->range[i].j1 = 0;
  gr->range[i].j2 = 0;

  gr->numrange--;
  return;
}

void
setrange (int serie, char *buf, char *name)
{
  Graph *gr;
  char *i1j1 = NULL;
  char *i2j2 = NULL;
  char *separ;

  int j;

  if (ActiveGraph == NULL)
    return;
  if (buf == NULL)
    return;

  separ = strchr (buf, ':');
  if (separ != NULL)
    {
      i1j1 = buf;
      i2j2 = separ + 1;
      separ[0] = '\0';
    }

  

  gr = ActiveGraph;
  j = serie - 1;
  if (serie > gr->numrange)
    gr->numrange = serie;
  
  if (separ != NULL && i1j1 != NULL)
    alphatonum (i1j1, &(gr->range[j]).i1, &(gr->range[j]).j1);
  if (separ != NULL && i2j2 != NULL)
    alphatonum (i2j2, &(gr->range[j]).i2, &(gr->range[j]).j2);
  if (name != NULL)
    if (strlen (name) > 0)
      strcpy (gr->range[j].name, name);


  
  
  
  

  return;
}

void
setgraphtype (type)
     int type;
{
  if (ActiveGraph != NULL)
    ActiveGraph->type = type;
}

int
gettype ()
{
  if (ActiveGraph != NULL)
    return ActiveGraph->type;
  return 0;
}

int
setgridh (Boolean on)
{
  if (ActiveGraph != NULL)
    graph_setgrid (ActiveGraph, 2, on);
  return 0;
}

int
setgridv (Boolean on)
{
  if (ActiveGraph != NULL)
    graph_setgrid (ActiveGraph, 1, on);
  return 0;
}

void
settitre1 (titre)
     char *titre;
{
  if (ActiveGraph == NULL || titre == NULL)
    return;

  if (strlen (titre) < 1)
    {
      ActiveGraph->HasTitle = False;
      title_free (&ActiveGraph->ChartTitle);
    }
  else
    {
      ActiveGraph->HasTitle = True;
      title_settext (&ActiveGraph->ChartTitle, titre);
    }
}

char *
gettitre1 ()
{
  if (ActiveGraph == NULL)
    return NULL;
  return ActiveGraph->ChartTitle.Text;
}

void
setXaxis (titre)
     char *titre;
{
  if (ActiveGraph == NULL || titre == NULL)
    return;

  if (strlen (titre) < 1)
    {
      ActiveGraph->Axes[xlCategory].HasTitle = False;
      title_free (&ActiveGraph->Axes[xlCategory].AxisTitle);
    }
  else
    {
      ActiveGraph->Axes[xlCategory].HasTitle = True;
      title_settext (&ActiveGraph->Axes[xlCategory].AxisTitle, titre);
    }
}

char *
getXaxis ()
{
  if (ActiveGraph == NULL)
    return NULL;
  return ActiveGraph->Axes[xlCategory].AxisTitle.Text;
}

void
setYaxis (titre)
     char *titre;
{
  if (ActiveGraph == NULL || titre == NULL)
    return;

  if (strlen (titre) < 1)
    {
      ActiveGraph->Axes[xlValue].HasTitle = False;
      title_free (&ActiveGraph->Axes[xlValue].AxisTitle);
    }
  else
    {
      ActiveGraph->Axes[xlValue].HasTitle = True;
      title_settext (&ActiveGraph->Axes[xlValue].AxisTitle, titre);
    }
}

char *
getYaxis ()
{
  if (ActiveGraph == NULL)
    return NULL;
  return ActiveGraph->Axes[xlValue].AxisTitle.Text;
}






int
getnumdra ()
{				
  return ActiveWorksheet->nbdrawing;
}

Drawing *
getdra (n)
{
  return ActiveWorksheet->Drawings[n];
}

Drawing *
newdra ()
{
  Drawing *activedra = worksheet_newdrawing (ActiveWorksheet);
  ActivateDrawing (activedra);
  return activedra;
}

Drawing *
getlastdra ()
{
  return ActiveDrawing;
}

int
setactivedra (n)
     int n;
{
  ActivateDrawing (ActiveWorksheet->Drawings[n]);
  return 0;
}

int
getactivedra ()
{
  int i;
  for (i = 0; i < getnumdra (); i++)
    if (ActiveDrawing == getdra (i))
      return i;
  return 0;
}

int
copydra ()
{
  if (ActiveDrawing == NULL)
    return 1;

  if (clipboarddrawing != NULL)
    freedrawing (clipboarddrawing);
  clipboarddrawing = newdrawing1 (ActiveDrawing);
  return 0;
}

int
cutdra ()
{

  if (ActiveWorksheet == NULL)
    return 1;
  if (ActiveDrawing == NULL)
    return 1;

  copydra ();

  worksheet_deldrawing (ActiveWorksheet, ActiveDrawing);

  ActiveDrawing = NULL;
  return 0;
}

int
pastedra ()
{

  if (clipboarddrawing == NULL)
    return 1;
  drawing_copy (worksheet_newdrawing (ActiveWorksheet), clipboarddrawing);
  return 0;
}



int
getnumbtn ()
{				
  return ActiveWorksheet->nbbutton;
}

Button *
getbtn (n)
{
  return ActiveWorksheet->Buttons[n];
}

Button *
newbtn ()
{
  Button *activebtn = worksheet_newbutton (ActiveWorksheet);
  ActivateButton (activebtn);
  return activebtn;
}

Button *
getlastbtn ()
{
  return ActiveButton;
}

int
setactivebtn (n)
     int n;
{
  ActivateButton (ActiveWorksheet->Buttons[n]);
  return 0;
}

int
getactivebtn ()
{
  int i;
  for (i = 0; i < getnumbtn (); i++)
    if (ActiveButton == getbtn (i))
      return i;
  return 0;
}

int
copybtn ()
{
  if (ActiveButton == NULL)
    return 0;
  return 0;


}

int
cutbtn ()
{
  int i, pos;

  if (ActiveButton == NULL)
    return 1;

  if (clipboardbutton != NULL)
    freebutton (clipboardbutton);	
  clipboardbutton = ActiveButton;

  pos = getactivebtn ();
  for (i = pos; i < getnumbtn () - 1; i++)
    ActiveWorksheet->Buttons[i] = ActiveWorksheet->Buttons[i + 1];
  ActiveWorksheet->nbbutton--;

  ActiveButton = NULL;

  return 0;
}

int
pastebtn ()
{
  if (clipboardbutton == NULL)
    return 1;
  return 0;

}
