#include "Globals.h"
#include "icon.h"


WriteItemList(FileName,arexx) /*Write the item list to disk*/
char *FileName;
BYTE arexx;
{
   BPTR fp;
   struct LineItem *CurItem;
   char chip buffer[100];

   if((fp=(BPTR)Open(FileName,MODE_NEWFILE))==NULL)
   {
      if(!arexx)
	 TitleError("Can't open file for save!");
      return(FALSE);
   }

   strcpy(buffer,"LDB3");  /*ID:  Liner Data Block version 3*/

   /*Store StartingLevel & double spacing flag as one byte on disk*/
   /*(holdover from the old data format)*/
   buffer[5]=StartingLevel+((prefs.DS) ? 32 : 0);
   Write(fp,buffer,6); /*Write out the header*/

   CurItem=(struct LineItem *)FirstItem;

   do	 /*Write each LineItem to the file*/
   {
      buffer[0]=strlen(CurItem->Text)+3;
      buffer[1]=CurItem->Level;
      buffer[2]=CurItem->ItemNumber;
      buffer[3]=CurItem->cont;
      strcpy(&buffer[4],CurItem->Text);
      Write(fp,buffer,buffer[0]+2);
      CurItem=(struct LineItem *)CurItem->NextItem;
   }
   while(CurItem != NULL);

   Close(fp);
   if(prefs.Icons)   /*Create an icon?*/
      PutDiskObject(FileName,&iconinfo);  /*If so, write it out*/

   return(TRUE);
}

extern void CreatePrefsIcon() /*Create an icon for liner.prefs*/
{
   if(prefs.Icons)
      PutDiskObject("liner:liner.prefs",&prefsiconinfo);
}

Old_ReadItemList(FileName,arexx)  /*Read a pre V1.5 item list from disk*/
char *FileName;
BYTE arexx;
{
   BPTR fp;
   struct Old_LineItem chip buffer;
   struct LineItem *CurItem;
   int len;
   char TempIndent;
   char text[80];

   if((fp=(BPTR)Open(FileName,MODE_OLDFILE))==NULL)
   {
      if(!arexx)
	 TitleError("Can't open file for read!");
      return(FALSE);
   }

   Read(fp,&buffer,sizeof(struct Old_LineItem));
   TempIndent=buffer.Text[4];
   buffer.Text[4]=NULL;
   if(strcmp(buffer.Text,"LFDB")) /*'Liner Format Data Block'*/
      {
      Close(fp);
      return(FALSE);
      }

   FreeListMem(FirstItem,LastItem); /*Get rid of old outline*/

   ModifyMenus(TempIndent);   /*Modify the Double Spacing and Starting Level*/
			      /*menus according to file being read in*/
   SetRowsInScreen();      /*Set the number of rows*/

   CurItem=FirstItem=FirstScrnItem=(struct LineItem *)InsertItem(NULL,NULL);
   if(CurItem==NULL)
   {
      CloseGraphics();
      CloseLibrary(IconBase);
      CloseLibrary(DosBase);
      Leave(100,"Memory too fragmented to continue!");
   }

   len=Read(fp,&buffer,sizeof(struct Old_LineItem));

   while(len > 0) /*While there is still data to be read,*/
   {		  /*read it*/
      struct LineItem *old;

      CurItem->ItemNumber=buffer.ItemNumber;
      CurItem->Level=buffer.Level;
      CurItem->cont=FALSE;
      strcpy(CurItem->Text,buffer.Text);
      len=Read(fp,&buffer,sizeof(struct Old_LineItem));
      strcpy(text,CurItem->Text);
      CurItem=(struct LineItem *)BreakLineApart(CurItem,NULL,text);
      old=(struct LineItem *)CurItem;
      CurItem=(struct LineItem *)InsertItem(NULL,CurItem);
      if(CurItem==NULL)
      {
	 LastItem=(struct LineItem *)old;
	 NewAll();
	 Leave(0,"Memory too fragmented to perform OPEN!");
	 return(FALSE);
      }
   }

   LastItem=(struct LineItem *)CurItem->PrevItem;
   LastItem->NextItem=NULL;
   Close(fp);

   PrintItemList(FirstItem,1);
   CurrentItem=(struct LineItem *)FirstItem;
   FreeMem(CurItem,sizeof(struct LineItem));
   PlotCursor(MinX(CurrentItem),1);
   return(TRUE);
}

ReadItemList(FileName,arexx)  /*Read an item list from disk*/
char *FileName;
BYTE arexx;
{
   BPTR fp;
   struct LineItem *CurItem;
   char chip buffer[100];
   int len;
   char TempIndent;

   if((fp=(BPTR)Open(FileName,MODE_OLDFILE))==NULL)
   {
      if(!arexx)
	 TitleError("Can't open file for read!");
      return(FALSE);
   }
   Read(fp,buffer,6);

   if(strcmp(buffer,"LDB3")) /*'Liner Data Block version 3'*/
   {
      Close(fp);  /*Try reading the old file format*/
      return(Old_ReadItemList(FileName,arexx));
   }

   TempIndent=buffer[5];
   FreeListMem(FirstItem,LastItem); /*Get rid of old outline*/

   ModifyMenus(TempIndent);   /*Modify the Double Spacing and Starting Level*/
			      /*menus according to file being read in*/
   SetRowsInScreen();      /*Set the number of rows*/

   CurItem=FirstItem=FirstScrnItem=(struct LineItem *)InsertItem(NULL,NULL);
   if(CurItem==NULL)
   {
      CloseGraphics();
      CloseLibrary(IconBase);
      CloseLibrary(DosBase);
      Leave(0,"Memory too fragmented to perform OPEN!");
      exit();
   }

   len=Read(fp,buffer,1);

   while(len > 0 )   /*While information is there*/
   {
      struct LineItem *old;

      Read(fp,buffer,buffer[0]+1);
      CurItem->Level=buffer[0]; /*Put it into a LineItem*/
      CurItem->ItemNumber=buffer[1];
      CurItem->cont=buffer[2];
      strcpy(CurItem->Text,&buffer[3]);
      len=Read(fp,buffer,1);
      old=(struct LineItem *)CurItem;
      CurItem=(struct LineItem *)InsertItem(NULL,CurItem);
      if(CurItem==NULL) /*Out of memory*/
      {
	 LastItem=(struct LineItem *)old;
	 NewAll();
	 Leave(0,"Memory too fragmented to perform OPEN!");
	 return(FALSE);
      }
   }

   LastItem=(struct LineItem *)CurItem->PrevItem;
   LastItem->NextItem=NULL;	 /*Delete the last LineItem*/
   FreeMem(CurItem,sizeof(struct LineItem));
   Close(fp);

   PrintItemList(FirstItem,1);   /*Print the new outline*/
   CurrentItem=(struct LineItem *)FirstItem; /*Put the cursor*/
   PlotCursor(MinX(CurrentItem),1);       /*at the top*/
   return(TRUE);

}

/*This function deals with the situation of having a line longer than*/
/*is currently supported for its level (the line lengths were shortened*/
/*slightly from 1.32 to 2.00).	This function puts any extra text onto a*/
/*continuation line that it tacks on after the too-long line.  It will*/
/*copy whole words if it can find them.  If the offending line has no*/
/*spaces, then it will be chopped into two pieces.  No data is lost*/

struct LineItem *BreakLineApart(Item,Next,text)
struct LineItem *Item,*Next;
char *text;
{
   BYTE len,c,max;
   struct LineItem *cont;

   len=(strlen(text));
   max=MaxLen(Item->Level);
   if(len>max) /*Checks to see if the line is too big.  This way, it*/
   {	 /*can be used as a check by the calling function.*/
      cont=(struct LineItem *)InsertItem(Next,Item);
      if(cont==NULL)
      {
	 Leave(0,"Memory too fragmented to perform operation!");
	 return(Item);
      }

      cont->cont=TRUE;
      cont->ItemNumber=Item->ItemNumber;
      cont->Level=Item->Level;

	 /*Search for a space (breaking apart on a word to make it*/
	 /*look nice)*/
      for(c=max;c>=len-max && text[c]!=' ';--c);
      if(c>=len-max && text[c]==' ')
      {     /*Found a space, so break the line apart there*/
	 strcpy(cont->Text,&text[c+1]);
	 text[c]=NULL;
      }
      else /*Otherwise, chop the line in two*/
      {
	 strcpy(cont->Text,&text[max]);
	 text[max]=NULL;
      }
      strcpy(Item->Text,text);
      return(cont);
   }
   strcpy(Item->Text,text);
   return(Item);
}

/*~~~End of disk.c*/

