/*  Xsqlmenu
 *  Copyright (C) 1996-2000 Kees Lemmens
 *
 *  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.
 *
 *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#include "Xsqldefs.h"
#include "Recorddefs.h"

void ShowerClose(FL_OBJECT *ob, long parent)
{
   FD_Shower *fd_Shw = (FD_Shower *)parent;
   Info_t *I = (Info_t *)fd_Shw->vdata;   
   if(I->Res != NULL) 
     sql_free_result(I->Res);

   FreeInfoStruct(I);
   
   fl_hide_form(fd_Shw->Shower);
   fl_free_form(fd_Shw->Shower);
}

void ShowerWriteFile(FL_OBJECT *ob, long parent)
{
   FD_Shower *fd_Shw = (FD_Shower *)parent;
   FILE *output;
   char *filename;
   int x,count;
   
   count = fl_get_browser_maxline(fd_Shw->Browser);

   filename = (char *)fl_show_fselector("Set Outputfile","","*","");
   if (filename == NULL)
      return;
   
   if((output = fopen(filename,"w")) == NULL)
   {  
      Message("Can't open output file");
      return;
   }
   for(x=1;x<=count;x++) /* browser starts with 1 */
   {
      fputs(fl_get_browser_line(fd_Shw->Browser,x),output);
      fputc('\n',output);
   }
   
   fclose(output);
   Message("Browser contents written to file");
}

void ShowerPrint(FL_OBJECT *ob, long parent)
{
   FD_Shower *fd_Shw = (FD_Shower *)parent;
   FILE *output;
   char *command;
   int x,count;
   
   count = fl_get_browser_maxline(fd_Shw->Browser);

   command = (char *)fl_show_input("Printer command",PRINTCMD);
   if (command == NULL || *command == '\0')
     return;
   
   if (fork() == 0) /* use fork avoids crashing main program if Broken pipe */
   {
      output = popen(command,"w");
      for(x=1;x<=count;x++) /* browser starts with line 1 */
      {
	 fputs(fl_get_browser_line(fd_Shw->Browser,x),output);
	 fputc('\n',output);
      }
      pclose(output);
      exit(0);
   }
   else
     signal(SIGCHLD,SIG_IGN); /* avoid defuncts */
}

void ShowerFontSize(FL_OBJECT *counter, long parent)
{
   FD_Shower *fd_Shw = (FD_Shower *)parent;
   int newsize   = (int) fl_get_counter_value(counter);

   fl_freeze_form(fd_Shw->Shower);
   fl_set_browser_fontsize(fd_Shw->Browser,newsize);
   
   fl_unfreeze_form(fd_Shw->Shower);
}

void BrowserModifier(FL_OBJECT *ob, long parent)
{
   FD_Shower *fd_Shw = (FD_Shower *)parent;
   Info_t *I = (Info_t *)fd_Shw->vdata;   
   SQL_ROW  row;
   int recnr;
   
   if((recnr = fl_get_browser(fd_Shw->Browser)) == 0)
     return; /* no selection made */
   
   if(I->Res == NULL)
   {
      Message("I->res is NULL !!");
      return;
   }
   
   sql_data_seek(I->Res,recnr - 1);
   row = sql_fetch_row(I->Res);
   
   OpenRecordForModify(row[I->Primkey],I);
}

FD_Shower *BuildShowerForm(Info_t *I, char *title, int mode)
{
   FD_Shower *fd_Shw;
   
   fd_Shw = create_form_Shower();
   fd_Shw->vdata = CopyInfoStruct(I); /* store all table info locally !! */
   
   fl_set_object_label(fd_Shw->Title,title);
   
   fl_set_counter_value(fd_Shw->FontSize,FONTSIZE);
   fl_set_counter_bounds(fd_Shw->FontSize,6.0,24.0);
   fl_set_counter_step(fd_Shw->FontSize,2.0,0.0);
   fl_set_counter_precision(fd_Shw->FontSize,0);

   /* callback only if used for normal queries, not for 
    * field description or free SQL query */
   switch(mode)
   {
    case ACTIVE:
      fl_set_browser_dblclick_callback(fd_Shw->Browser,
				       BrowserModifier,(long)fd_Shw);
      fl_activate_object(fd_Shw->Modify);
      fl_set_object_lcol(fd_Shw->Modify,FL_BLACK);
      break;
      
    case KEYFIELD:
      fl_set_browser_dblclick_callback(fd_Shw->Browser,
				       SetPrimaryKey,(long)fd_Shw);
      fd_Shw->ldata = (long)I;
      
      /* we need the original pointer to change the primary key but cannot
         use vdata as the close callback always frees the vdata handle !
       */
      
      /* continue with next item : */

    case PASSIVE:
      fl_deactivate_object(fd_Shw->Modify);
      fl_set_object_lcol(fd_Shw->Modify,FL_INACTIVE_COL);
      break;
   }
   
   fl_set_browser_fontsize(fd_Shw->Browser ,FONTSIZE);
   fl_set_browser_fontstyle(fd_Shw->Browser ,FL_FIXEDBOLD_STYLE);
   
   fl_show_form(fd_Shw->Shower,
		FL_PLACE_MOUSE|FL_FREE_SIZE,FL_FULLBORDER,"Shower");

   return fd_Shw;
}

/* faster routine than using strcat() as in version 1.02 */
void AppendSpaces(char *buffer,int number)
{
   int y;
   while(*buffer != '\0' ) buffer++;
   
   for(y=0; y<number; y++)
     *buffer++ = ' ';
   *buffer = '\0';
}

void WriteToBrowser(Info_t *I,FL_OBJECT *ob,SQL_ROW row)
{
   char *buffer;
   char *sep = "  ";
   int len=0, y;
   
   for (y=0;y<I->Numflds;y++)
     len += I->Fields[y].length + strlen(sep);
   buffer = (char *) malloc(len * sizeof(char));
   
   *buffer = '\0';
   for(y=0;y<I->Numflds;y++)
   {  
      /* Work around a bug in the Linux strncat() function
       * it crashes if source == NULL in some versions.
       */
      if(row[y] == NULL)
	 AppendSpaces(buffer,I->Fields[y].length);
      else
      {
	 strncat(buffer,row[y],I->Fields[y].length);
	 AppendSpaces(buffer,I->Fields[y].length-strlen(row[y]));
      }
      strcat(buffer,sep);
   }
   
   fl_add_browser_line(ob,buffer);
   free(buffer);   
}

void XsqlShowAll(FL_OBJECT *ob, long parent)
{
   FD_Xsql   *Xsql = (FD_Xsql *)parent;
   Info_t    *I    = (Info_t *) Xsql->vdata;
   FD_Shower *fd_Shw;
   Info_t     *L;
   SQL_ROW    row;
   int        x,numrows;
   char       query[MAXQUERY];
   
   if(CheckTableSelected(Xsql) < 0)
     return;

   sprintf(query,SELECT ORDER,I->Table,I->Fields[I->Primkey].name);
   
   if (ExecuteQuery(I,query))
      return;
   
   fd_Shw = BuildShowerForm(I,"Show All Records",ACTIVE);

   L = (Info_t *) fd_Shw->vdata;
   L->Res = sql_store_result(sock);

   numrows = sql_num_rows(L->Res);/* get number of records in selection */
   
   fl_freeze_form(fd_Shw->Shower);

   for(x=0;x < numrows;x++)
   {
      if((row = sql_fetch_row(L->Res)) == NULL)
      {
	 SqlError("Error reading record !");
 	 return;
      }
      WriteToBrowser(L,fd_Shw->Browser,row);
   }
   fl_unfreeze_form(fd_Shw->Shower);
}

