/*  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 "Xsqldefs.h"

void WriteFieldLines(FD_Shower *fd_Shw, Info_t *I)
{
   char buffer[MAXSTRING];
   char *type;
   int x;

   fl_freeze_form(fd_Shw->Shower);
   
   sprintf(buffer,"%18s %18s %8s %8s %12s %8s","Fieldname","Tablename",
	   "Length","Type","Unique Key","Not Null");
   fl_add_browser_line(fd_Shw->Browser,buffer);
   
   for(x=0;x < I->Allflds;x++)
   {
      switch(I->Fields[x].type)
      {
#ifdef USE_MYSQL
       case FIELD_TYPE_STRING: type = "String"; break;
       case FIELD_TYPE_VAR_STRING: type = "VarString"; break;
       case FIELD_TYPE_FLOAT: type = "Float";      break;
       case FIELD_TYPE_DOUBLE: type = "Double";      break;
       case FIELD_TYPE_LONGLONG: case FIELD_TYPE_INT24:
       case FIELD_TYPE_DECIMAL: case FIELD_TYPE_TINY:
       case FIELD_TYPE_SHORT: case FIELD_TYPE_LONG: type = "Integer"; break;
       case FIELD_TYPE_DATE: type = "Date";	   break;
       case FIELD_TYPE_TIME: type = "Time"; break;
       case FIELD_TYPE_TIMESTAMP: type = "TimeStamp"; break;
       case FIELD_TYPE_DATETIME: type = "Datetime"; break;
       case FIELD_TYPE_YEAR: type = "Year"; break;
       case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_MEDIUM_BLOB:
       case FIELD_TYPE_LONG_BLOB: case FIELD_TYPE_BLOB: type = "Blob:"; break; 
#else
       case CHAR_TYPE: type = "Character"; break;
       case TEXT_TYPE: type = "Free text"; break;
       case INT_TYPE : type = "Integer";   break;
       case REAL_TYPE: type = "Real";      break;
       case IDX_TYPE : type = "Index";     break;
/* JJG 8-DEC-98 added new types found in mSQL 2.0.3 */
       case UINT_TYPE: type = "Unsigned integer";	break;
       case DATE_TYPE: type = "Date";	   break;
       case MONEY_TYPE: type = "Money";    break;
       case TIME_TYPE: type = "Time"; break;
#endif

       default:
	 Message("Unknown fieldtype detected !");
	 type = "Unknown"; break;
      }
      
      sprintf(buffer,"@C%c%18s %18s %6d   %10s %8s %8s",
	      x == I->Primkey ? '1' : '0', /* primary key color */
	      I->Fields[x].name,
	      I->Table,I->Fields[x].length,
	      type,IS_UNIQUE(I->Fields[x].flags) ? "Y" : "N",
	      IS_NOT_NULL(I->Fields[x].flags) ? "Y" : "N"
	      );
      
      fl_add_browser_line(fd_Shw->Browser,buffer);
   }
   fl_unfreeze_form(fd_Shw->Shower);
}

void SetPrimaryKey(FL_OBJECT *ob, long parent) /* callback */
{
   FD_Shower *fd_Shw = (FD_Shower *)parent;
   Info_t *I = (Info_t *)fd_Shw->ldata;
   int linenr;
   
   if((linenr = fl_get_browser(fd_Shw->Browser)) < 2)
     return; /* no selection made or headerline selected */
   
   if(I == NULL)
   {
      Message("Info struct is NULL !!");
      return;
   }
#ifndef USE_MYSQL
   if(I->Fields[linenr - 2].type == IDX_TYPE)
   {  
      Message("Can't use an index as primary key !");
      return;
   }
#endif      

   I->Primkey = linenr - 2; /* also counts header line ! */
   fl_clear_browser(fd_Shw->Browser);
   WriteFieldLines(fd_Shw,I);
}

int GetPrimaryKey(Info_t *I)
{
   int y;
   
#ifdef USE_MYSQL
   /* Find unique primary key */
   for(y=0;y<I->Allflds;y++)
   {
     if(IS_PRI_KEY(I->Fields[y].flags)&&IS_UNIQUE(I->Fields[y].flags))
       return y;
   }
   /* Else, find first unique key */
   for(y=0;y<I->Allflds;y++)
   {
     if(IS_UNIQUE(I->Fields[y].flags))
       return y;
   }
   /* Else, find primary key */
   for(y=0;y<I->Allflds;y++)
   {
     if(IS_PRI_KEY(I->Fields[y].flags))
       return y;
   }
   Message("No unique or primary key field found for this table !");
   y=0;
   return y;
#else
   SQL_RES *indexes;
   char *primkeyname;

   for(y=0;y<I->Allflds;y++)
   {
      if(IS_UNIQUE(I->Fields[y].flags))
	break;
   }
   
   if(y>=I->Allflds)
   {
      Message("No unique indexes found for this table: "
	      "using first field as the primary key.\n"
	      "You can set the primary key in the Field Info window.");
      return 0;
   }
   
   /* if more than one field is used for an index : exit with error */ 
   /* if more than one unique index : exit with error */

   indexes = msqlListIndex(sock,I->Table,I->Fields[y].name);
   
   sql_data_seek(indexes,1); /* number 1 is the index type  ! */
   primkeyname = *sql_fetch_row(indexes);

   for(y=0;y<I->Numflds;y++)
   {
      if(strncmp(I->Fields[y].name,primkeyname,strlen(I->Fields[y].name)) == 0)
	break;
   }
   if(y >= I->Numflds)
   {
      Message("No unique primary key field found for this table !");
      y=0;
   }
   
   sql_free_result(indexes);
   return y;
#endif
}

void XsqlFieldInfo(FL_OBJECT *ob, long parent)
{
   FD_Xsql *Xsql = (FD_Xsql *)parent;
   Info_t  *I    = (Info_t *) Xsql->vdata;
   FD_Shower *fd_Shw;
   
   if(CheckTableSelected(Xsql) < 0)
     return;
   
   fd_Shw = BuildShowerForm(I,"Field descriptions",KEYFIELD);
   
   WriteFieldLines(fd_Shw,I);
}
