//
// The Fusion Library Interface for DOS
// Version 1.02
// Copyright (C) 1990, 1991
// Software Dimensions
//
// Dialog Development System
//

#include "elements.h"
#include "fliwin.h"
#include "dds.h"

#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <alloc.h>
#include <string.h>

//-------------------------------------------------------------------------
//
// Load a saved file
//
//-------------------------------------------------------------------------

#define CurrentFileVersion 6

void stringread(int Save,char *String)
{
  int Length;
  read(Save,&Length,sizeof(int));
  read(Save,String,Length);
}

void DialogWindow::LoadFile(char *File)
{
  if (MainHandler)
    RemoveTheMenus();

  //-------------------------------------------------------------------------
  //
  // Verify file existance
  //
  //-------------------------------------------------------------------------

  if (access(File,0))
    return;

  //-------------------------------------------------------------------------
  //
  // Open file for load
  //
  //-------------------------------------------------------------------------

  int Save=open(File,O_RDWR|O_BINARY,S_IREAD|S_IWRITE);
  lseek(Save,0,SEEK_SET);

  //-------------------------------------------------------------------------
  //
  // Get DDS file signature and verify it.  This will ensure that a user
  // cannot load a file that does not belong to the DDS.  In addition,
  // this will also keep the users from trying to crash the DDS.
  //
  //-------------------------------------------------------------------------

  char FileSignature[] = "[DDS/SD]";
  char CheckSignature[sizeof(FileSignature)];

  read(Save,&CheckSignature,sizeof(FileSignature));

  if (strcmp(FileSignature,CheckSignature))
  {
    InfoBox NotValid;

    NotValid
      + "The signature at the start of this"
      + "file is incorrect which means that"
      + "the file you specified is not a"
      + "a DDS file or it is a file that has"
      + "been corrupted.";

    NotValid.Title("Signature Wrong");
    NotValid.UseInfoBox();

    close(Save);

    return;
  }

  //-------------------------------------------------------------------------
  //
  // If pieces are currently in memory, dump them out
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0;i<NumberPieces;i++)
      delete Pieces[i];
    free(Pieces);
    Pieces=0;
  }

  //-------------------------------------------------------------------------
  //
  // Freshen the screen storage buffer
  //
  //-------------------------------------------------------------------------

  for (int y=0;y<60;y++)
    for (int x=0;x<sizeof(Interior[0]);x+=2)
    {
      *(Interior[y]+x)=0;
      *(Interior[y]+x+1)=WinInterior;
    }

  //-------------------------------------------------------------------------
  //
  // Get file version code.
  //
  // File version history:
  //  Version 1 - DDS betas 1 to 5
  //  Version 2 - between DDS beta 5 and 6 (in house structure changes)
  //    Version 2 eliminates some unneeded data and handles some new
  //    fields that were added during testing.
  //  Version 3 - incorporates new load structures for help and derivisions
  //  Version 4 - permits additional element and object types to be
  //    added in future versions with a version change being required.  It
  //    also incorporates new pick list styles and character formats into
  //    the loader.
  //  Version 5 - added new focuses for buttons and resets for char/nums
  //  Version 6 - added a string stripper function that only saves the
  //    actual size of the string versus the entire string.
  //
  // This loader is compatible with *all* file versions
  //
  //-------------------------------------------------------------------------

  int CurVersion;

  if (!Title)
    Title=new char[50];

  //-------------------------------------------------------------------------
  //
  // Load global dialog characteristics
  //
  //-------------------------------------------------------------------------

  read(Save,&CurVersion,sizeof(int));
  read(Save,&CurrentColor,sizeof(int));
  read(Save,&ZPositioning,sizeof(int));

  if (CurVersion<6)
  {
    read(Save,Title,50);
    read(Save,&DerivedClass,50);
  }
  else
  {
    stringread(Save,Title);
    stringread(Save,DerivedClass);
  }

  if (CurVersion==1)
  {
    // These variables are obsolete in file version 2
    // and are loaded to nowhere land

    char FunctionName[50];
    read(Save,&FunctionName,50);
    int OutputOutside;
    read(Save,&OutputOutside,sizeof(int));
  }

  read(Save,&Width,sizeof(int));
  read(Save,&Height,sizeof(int));
  read(Save,&X,sizeof(int));
  read(Save,&Y,sizeof(int));

  //-------------------------------------------------------------------------
  //
  // Load the text that appears inside of the window (the typed stuff)
  //
  //-------------------------------------------------------------------------

  for (int i=0;i<(Height-2);i++)
    read(Save,Interior[i],(Width-2)*2);

  //-------------------------------------------------------------------------
  //
  // Load the piece count
  //
  //-------------------------------------------------------------------------

  read(Save,&NumberPieces,sizeof(int));

  //-------------------------------------------------------------------------
  //
  // Load the elements in the order in which they were in when the
  // dialog was saved and last manipulated
  //
  // This first section allocates a class for each element and object
  // after getting the signature of the type of object
  //
  //-------------------------------------------------------------------------

  //-------------------------------------------------------------------------
  //
  // This GoIt enumeration is designed to make the load compabitible with
  // file versions 1 to 3.  DO NOT alter or remove it or you can have
  // problems!!
  //
  //-------------------------------------------------------------------------

	enum GoIt
	{

    // Objects

    V3Box = 0,
		V3FilledBox,
		V3HorizontalLine,
		V3VerticalLine,
		V3Shadow,
		V3EraseArea,
    V3ColorizeArea,
    V3__DUMMY__,

    // Elements

    V3Character,
    V3Integer,
    V3Long,
    V3Float,
    V3Double,
    V3Bcd,
    V3VRadio,
    V3HRadio,
    V3Pick,
    V3Check,
    V3Push,
    V3__DUMMY2__,

    // Non Classifiable

    V3GroupHeading
  };

  //-------------------------------------------------------------------------
  //
  // This loader segment loads file versions 1 to 3.
  //
  // DO NOT alter or remove it or you can have problems with old versions!!
  //
  //-------------------------------------------------------------------------

  if (CurVersion<4)
  {

  if (NumberPieces)
  {
    Pieces=(PieceHandler **)realloc(Pieces,(NumberPieces+1)*sizeof(PieceHandler *));

    for (i=0;i<NumberPieces;i++)
    {
      int Layout;

      read(Save,&Layout,sizeof(int));

      switch (Layout)
      {
        case V3Box:
          Pieces[i]=new Box(&Blaze);
          break;

        case V3FilledBox:
          Pieces[i]=new FilledBox(&Blaze);
          break;

        case V3HorizontalLine:
          Pieces[i]=new HorizontalLine(&Blaze);
          break;

        case V3VerticalLine:
          Pieces[i]=new VerticalLine(&Blaze);
          break;

        case V3Shadow:
          Pieces[i]=new Shadow(&Blaze);
          break;

        case V3EraseArea:
          Pieces[i]=new EraseArea(&Blaze);
          break;

        case V3ColorizeArea:
          Pieces[i]=new ColorizeArea(&Blaze);
          break;

        case V3Character:
          Pieces[i]=new Character(&Blaze);
          break;

        case V3Integer:
          Pieces[i]=new Integer(&Blaze);
          break;

        case V3Long:
          Pieces[i]=new Long(&Blaze);
          break;

        case V3Float:
          Pieces[i]=new Float(&Blaze);
          break;

        case V3Double:
          Pieces[i]=new Double(&Blaze);
          break;

        case V3Bcd:
          Pieces[i]=new Bcd(&Blaze);
          break;

        case V3Check:
          Pieces[i]=new Check(&Blaze);
          break;

        case V3Push:
          Pieces[i]=new Push(&Blaze);
          break;

        case V3GroupHeading:
          Pieces[i]=new GroupHeading(&Blaze);
          break;

        case V3HRadio:
          Pieces[i]=new HRadio(&Blaze);
          break;

        case V3VRadio:
          Pieces[i]=new VRadio(&Blaze);
          break;
      }

      //----------------------------------------------------------------------
      //
      // This set of variables is saved in the same spot for all elements.
      //
      //----------------------------------------------------------------------

      read(Save,&Pieces[i]->X,sizeof(int));
      read(Save,&Pieces[i]->Y,sizeof(int));
      read(Save,&Pieces[i]->Width,sizeof(int));
      read(Save,&Pieces[i]->Height,sizeof(int));
      read(Save,&Pieces[i]->Color,sizeof(int));

      //----------------------------------------------------------------------
      //
      // Load information that is specific to each type of element or
      // object.
      //
      //----------------------------------------------------------------------

      switch(Layout)
      {
        case V3Character:
        case V3Integer:
        case V3Long:
        case V3Float:
        case V3Double:
        case V3Bcd:
          Pieces[i]->Mask=new char[50];
          read(Save,Pieces[i]->Mask,50);
          Pieces[i]->Variable=new char[50];
          read(Save,Pieces[i]->Variable,50);
          Pieces[i]->Prompter=new char[50];
          read(Save,Pieces[i]->Prompter,50);
          Pieces[i]->HotKey=new char[30];
          read(Save,Pieces[i]->HotKey,30);
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          read(Save,&Pieces[i]->PromptX,sizeof(int));
          read(Save,&Pieces[i]->PromptY,sizeof(int));
          if (CurVersion>2)
          {
            Pieces[i]->DerivedClass=new char[50];
            read(Save,Pieces[i]->DerivedClass,50);
            Pieces[i]->Help=new char[65];
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            Pieces[i]->DerivedClass=new char[50];
            *(Pieces[i]->DerivedClass)=0;
            Pieces[i]->Help=new char[65];
            *(Pieces[i]->Help)=0;
          }
          break;
        case V3Check:
          Pieces[i]->Text=new char[50];
          read(Save,Pieces[i]->Text,50);
          Pieces[i]->Variable=new char[50];
          read(Save,Pieces[i]->Variable,50);
          Pieces[i]->HotKey=new char[30];
          read(Save,Pieces[i]->HotKey,30);
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          if (CurVersion>2)
          {
            Pieces[i]->DerivedClass=new char[50];
            read(Save,Pieces[i]->DerivedClass,50);
            Pieces[i]->Help=new char[65];
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            Pieces[i]->DerivedClass=new char[50];
            *(Pieces[i]->DerivedClass)=0;
            Pieces[i]->Help=new char[65];
            *(Pieces[i]->Help)=0;
          }
          break;
        case V3Push:
          Pieces[i]->Text=new char[50];
          read(Save,Pieces[i]->Text,50);
          Pieces[i]->Constant=new char[50];
          read(Save,Pieces[i]->Constant,50);
          Pieces[i]->HotKey=new char[30];
          read(Save,Pieces[i]->HotKey,30);
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          if (CurVersion>2)
          {
            Pieces[i]->DerivedClass=new char[50];
            read(Save,Pieces[i]->DerivedClass,50);
            Pieces[i]->Help=new char[65];
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            Pieces[i]->DerivedClass=new char[50];
            *(Pieces[i]->DerivedClass)=0;
            Pieces[i]->Help=new char[65];
            *(Pieces[i]->Help)=0;
          }
          break;
        case V3GroupHeading:
          Pieces[i]->Text=new char[50];
          read(Save,Pieces[i]->Text,50);
          Pieces[i]->HotKey=new char[30];
          read(Save,Pieces[i]->HotKey,30);
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          break;
        case V3VRadio:
        case V3HRadio:
          Pieces[i]->Variable=new char[50];
          read(Save,Pieces[i]->Variable,50);
          Pieces[i]->Prompter=new char[50];
          read(Save,Pieces[i]->Prompter,50);
          Pieces[i]->HotKey=new char[30];
          read(Save,Pieces[i]->HotKey,30);
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          read(Save,&Pieces[i]->PromptX,sizeof(int));
          read(Save,&Pieces[i]->PromptY,sizeof(int));
          Pieces[i]->DerivedClass=new char[50];
          read(Save,Pieces[i]->DerivedClass,50);
          Pieces[i]->Help=new char[65];
          read(Save,Pieces[i]->Help,65);
          Pieces[i]->Elements=new char*[10];
          for (int j=0;j<10;j++)
          {
            Pieces[i]->Elements[j]=new char[50];
            read(Save,Pieces[i]->Elements[j],50);
          }
          break;
      }
    }
  }

  }
  else
  {

  //-------------------------------------------------------------------------
  //
  // This loader segment loads file versions 4 and above.
  //
  // The enumerations for this segment are in PIECE.H
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    Pieces=(PieceHandler **)realloc(Pieces,(NumberPieces+1)*sizeof(PieceHandler *));

    for (i=0;i<NumberPieces;i++)
    {
      int Layout;

      read(Save,&Layout,sizeof(int));

      switch (Layout)
      {
        case PieceHandler::Box:
          Pieces[i]=new Box(&Blaze);
          break;

        case PieceHandler::FilledBox:
          Pieces[i]=new FilledBox(&Blaze);
          break;

        case PieceHandler::HorizontalLine:
          Pieces[i]=new HorizontalLine(&Blaze);
          break;

        case PieceHandler::VerticalLine:
          Pieces[i]=new VerticalLine(&Blaze);
          break;

        case PieceHandler::Shadow:
          Pieces[i]=new Shadow(&Blaze);
          break;

        case PieceHandler::EraseArea:
          Pieces[i]=new EraseArea(&Blaze);
          break;

        case PieceHandler::ColorizeArea:
          Pieces[i]=new ColorizeArea(&Blaze);
          break;

        case PieceHandler::Character:
          Pieces[i]=new Character(&Blaze);
          break;

        case PieceHandler::Integer:
          Pieces[i]=new Integer(&Blaze);
          break;

        case PieceHandler::Long:
          Pieces[i]=new Long(&Blaze);
          break;

        case PieceHandler::Float:
          Pieces[i]=new Float(&Blaze);
          break;

        case PieceHandler::Double:
          Pieces[i]=new Double(&Blaze);
          break;

        case PieceHandler::Bcd:
          Pieces[i]=new Bcd(&Blaze);
          break;

        case PieceHandler::Check:
          Pieces[i]=new Check(&Blaze);
          break;

        case PieceHandler::Push:
          Pieces[i]=new Push(&Blaze);
          break;

        case PieceHandler::GroupHeading:
          Pieces[i]=new GroupHeading(&Blaze);
          break;

        case PieceHandler::HRadio:
          Pieces[i]=new HRadio(&Blaze);
          break;

        case PieceHandler::VRadio:
          Pieces[i]=new VRadio(&Blaze);
          break;

        case PieceHandler::PickGeneric:
          Pieces[i]=new PickGeneric(&Blaze);
          break;
      }

      //----------------------------------------------------------------------
      //
      // This set of variables is saved in the same spot for all elements.
      //
      //----------------------------------------------------------------------

      read(Save,&Pieces[i]->X,sizeof(int));
      read(Save,&Pieces[i]->Y,sizeof(int));
      read(Save,&Pieces[i]->Width,sizeof(int));
      read(Save,&Pieces[i]->Height,sizeof(int));
      read(Save,&Pieces[i]->Color,sizeof(int));

      //----------------------------------------------------------------------
      //
      // Load information that is specific to each type of element or
      // object.
      //
      //----------------------------------------------------------------------

      switch(Layout)
      {
        case PieceHandler::Character:
        case PieceHandler::Integer:
        case PieceHandler::Long:
        case PieceHandler::Float:
        case PieceHandler::Double:
        case PieceHandler::Bcd:
          Pieces[i]->Mask=new char[50];
          Pieces[i]->Variable=new char[50];
          Pieces[i]->Prompter=new char[50];
          Pieces[i]->HotKey=new char[30];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->Mask,50);
            read(Save,Pieces[i]->Variable,50);
            read(Save,Pieces[i]->Prompter,50);
            read(Save,Pieces[i]->HotKey,30);
          }
          else
          {
            stringread(Save,Pieces[i]->Mask);
            stringread(Save,Pieces[i]->Variable);
            stringread(Save,Pieces[i]->Prompter);
            stringread(Save,Pieces[i]->HotKey);
          }
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          read(Save,&Pieces[i]->PromptX,sizeof(int));
          read(Save,&Pieces[i]->PromptY,sizeof(int));
          Pieces[i]->DerivedClass=new char[50];
          Pieces[i]->Help=new char[65];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->DerivedClass,50);
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            stringread(Save,Pieces[i]->DerivedClass);
            stringread(Save,Pieces[i]->Help);
          }
          if (CurVersion>=5)
            read(Save,&Pieces[i]->Focus_Reset,sizeof(int));
          if (Layout==PieceHandler::Character)
          {
            read(Save,&Pieces[i]->MaskCharacter,sizeof(int));
            read(Save,&Pieces[i]->MaskWidth,sizeof(int));
            read(Save,&Pieces[i]->ScrollWidth,sizeof(int));
          }
          break;
        case PieceHandler::Check:
          Pieces[i]->Text=new char[50];
          Pieces[i]->Variable=new char[50];
          Pieces[i]->HotKey=new char[30];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->Text,50);
            read(Save,Pieces[i]->Variable,50);
            read(Save,Pieces[i]->HotKey,30);
          }
          else
          {
            stringread(Save,Pieces[i]->Text);
            stringread(Save,Pieces[i]->Variable);
            stringread(Save,Pieces[i]->HotKey);
          }
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          Pieces[i]->DerivedClass=new char[50];
          Pieces[i]->Help=new char[65];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->DerivedClass,50);
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            stringread(Save,Pieces[i]->DerivedClass);
            stringread(Save,Pieces[i]->Help);
          }
          break;
        case PieceHandler::Push:
          Pieces[i]->Text=new char[50];
          Pieces[i]->Constant=new char[50];
          Pieces[i]->HotKey=new char[30];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->Text,50);
            read(Save,Pieces[i]->Constant,50);
            read(Save,Pieces[i]->HotKey,30);
          }
          else
          {
            stringread(Save,Pieces[i]->Text);
            stringread(Save,Pieces[i]->Constant);
            stringread(Save,Pieces[i]->HotKey);
          }
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          Pieces[i]->DerivedClass=new char[50];
          Pieces[i]->Help=new char[65];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->DerivedClass,50);
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            stringread(Save,Pieces[i]->DerivedClass);
            stringread(Save,Pieces[i]->Help);
          }
          if (CurVersion>=5)
            read(Save,&Pieces[i]->Focus_Reset,sizeof(int));
          break;
        case PieceHandler::GroupHeading:
          Pieces[i]->Text=new char[50];
          Pieces[i]->HotKey=new char[30];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->Text,50);
            read(Save,Pieces[i]->HotKey,30);
          }
          else
          {
            stringread(Save,Pieces[i]->Text);
            stringread(Save,Pieces[i]->HotKey);
          }
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          break;
        case PieceHandler::VRadio:
        case PieceHandler::HRadio:
          Pieces[i]->Variable=new char[50];
          Pieces[i]->Prompter=new char[50];
          Pieces[i]->HotKey=new char[30];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->Variable,50);
            read(Save,Pieces[i]->Prompter,50);
            read(Save,Pieces[i]->HotKey,30);
          }
          else
          {
            stringread(Save,Pieces[i]->Variable);
            stringread(Save,Pieces[i]->Prompter);
            stringread(Save,Pieces[i]->HotKey);
          }
          read(Save,&Pieces[i]->GroupCode,sizeof(int));
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          read(Save,&Pieces[i]->PromptX,sizeof(int));
          read(Save,&Pieces[i]->PromptY,sizeof(int));
          Pieces[i]->DerivedClass=new char[50];
          Pieces[i]->Help=new char[65];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->DerivedClass,50);
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            stringread(Save,Pieces[i]->DerivedClass);
            stringread(Save,Pieces[i]->Help);
          }
          Pieces[i]->Elements=new char*[10];
          for (int j=0;j<10;j++)
          {
            Pieces[i]->Elements[j]=new char[50];
            if (CurVersion<6)
              read(Save,Pieces[i]->Elements[j],50);
            else
              stringread(Save,Pieces[i]->Elements[j]);
          }
          break;
        case PieceHandler::PickGeneric:
          Pieces[i]->Prompter=new char[50];
          Pieces[i]->HotKey=new char[30];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->Prompter,50);
            read(Save,Pieces[i]->HotKey,30);
          }
          else
          {
            stringread(Save,Pieces[i]->Prompter);
            stringread(Save,Pieces[i]->HotKey);
          }
          read(Save,&Pieces[i]->HelpId,sizeof(int));
          read(Save,&Pieces[i]->ToBeDerived,sizeof(int));
          read(Save,&Pieces[i]->PromptX,sizeof(int));
          read(Save,&Pieces[i]->PromptY,sizeof(int));
          Pieces[i]->DerivedClass=new char[50];
          Pieces[i]->Help=new char[65];
          if (CurVersion<6)
          {
            read(Save,Pieces[i]->DerivedClass,50);
            read(Save,Pieces[i]->Help,65);
          }
          else
          {
            stringread(Save,Pieces[i]->DerivedClass);
            stringread(Save,Pieces[i]->Help);
          }
          break;
      }
    }
  }

  }

  close(Save);
}

