/*****************************************************************************
*   Module to load EEDraw files.					     *
*									     *
* Written by:  Gershon Elber			IBM PC Ver 1.0,	Oct. 1989    *
*****************************************************************************/

#include <stdio.h>
#include <string.h>

#ifdef __MSDOS__
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <alloc.h>
#endif /* __MSDOS__ */

#include "program.h"
#include "eelibs.h"
#include "eeredraw.h"
#include "eeload.h"
#include "eelayer.h"
#include "virtrstr.h"

#define EEDRAW_FILE_STAMP "EEDraw"
#define NULL_STRING "_NONAME_"

/*****************************************************************************
* Routine to load an EEDraw file.					     *
* Save in LoadedFileName the name of the file loaded to reset it to an       *
 * empty string if none loaded.						     *
*****************************************************************************/
void LoadEEFile(FILE *f)
{
    char Line[LINE_LEN], Name1[LINE_LEN_SHORT], Name2[LINE_LEN_SHORT],
			 Char1[LINE_LEN_SHORT], Char2[LINE_LEN_SHORT];
    int i, LineCount = 1;
    BooleanType Failed = FALSE;
    DrawGenericStruct *Phead, *Pnext;
    DrawLibItemStruct *LibItemStruct;
    DrawConnectionStruct *ConnectionStruct;
    DrawPolylineStruct *PolylineStruct;
    DrawTextStruct *TextStruct;

    if (fgets(Line, LINE_LEN - 1, f) == NULL ||
	strncmp(Line, EEDRAW_FILE_STAMP, sizeof(EEDRAW_FILE_STAMP) - 1) != 0) {
	fclose(f);
	FatalError("Given file is NOT EEDraw file");
    }

    if (fgets(Line, LINE_LEN - 1, f) == NULL ||
	strncmp(Line, "LIBS:", 5) != 0) {
	fclose(f);
	FatalError("Given file is NOT EEDraw file");
    }
    else
	LoadLibraries(&Line[5]);

SeedLayers();			/* Set the default Layers up + Layer Array */
LoadLayers(f);
    while (!feof(f) &&
	   fgets(Line, LINE_LEN - 1, f) != NULL) {
	LineCount++;

	switch(Line[0]) {
	    case 'L':				      /* Its a library item. */
		LibItemStruct = (DrawLibItemStruct *)
		    			MyMalloc(sizeof(DrawLibItemStruct));
		LibItemStruct -> StructType = DRAW_LIB_ITEM_STRUCT_TYPE;
		if (sscanf(&Line[1], "%s %s %s %s %d %d %d %d",
			   Name1, Name2,
			   Char1, Char2,
			   &LibItemStruct -> ChipNameX,
			   &LibItemStruct -> ChipNameY,
			   &LibItemStruct -> PartNameX,
			   &LibItemStruct -> PartNameY) != 8 ||
		    (Char1[0] != 'V' && Char1[0] != 'H') ||
		    (Char2[0] != 'V' && Char2[0] != 'H')) {
		    sprintf(Line,
			"EEDraw file lib item struct error at line %d, aborted",
								LineCount);
		    Failed = TRUE;
		    break;
		}
		LibItemStruct -> ChipNameOrient =
		    Char1[0] == 'V' ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ;
		LibItemStruct -> PartNameOrient =
		    Char2[0] == 'V' ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ;

		if (strcmp(Name1, NULL_STRING) != 0) {
		    for (i = 0; i < strlen(Name1); i++)
			if (Name1[i] == '~') Name1[i] = ' ';
		    LibItemStruct -> ChipName = strdup(Name1);
		}
		else {
		    LibItemStruct -> ChipName = NULL;
		    LibItemStruct -> ChipNameOrient = TEXT_ORIENT_NON;
		}

		if (strcmp(Name2, NULL_STRING) != 0) {
		    for (i = 0; i < strlen(Name2); i++)
			if (Name2[i] == '~') Name2[i] = ' ';
		    LibItemStruct -> PartName = strdup(Name2);
		}
		else {
		    LibItemStruct -> PartName = NULL;
		    LibItemStruct -> PartNameOrient = TEXT_ORIENT_NON;
		}

		LineCount++;
		if (!Failed &&
		    (fgets(Line, LINE_LEN - 1, f) == NULL ||
		     sscanf(Line, "%d %d %d %d %d %d %d",
			    &LibItemStruct -> Multi,
			    &LibItemStruct -> PosX,
			    &LibItemStruct -> PosY,
			    &LibItemStruct -> BBoxMinX,
			    &LibItemStruct -> BBoxMinY,
			    &LibItemStruct -> BBoxMaxX,
			    &LibItemStruct -> BBoxMaxY) != 7)) {
		    Failed = TRUE;
		    break;
		}

		LineCount++;
		if (!Failed &&
		    (fgets(Line, LINE_LEN - 1, f) == NULL ||
		     sscanf(Line, "%d %d %d %d",
			    &LibItemStruct -> Transform[0][0],
			    &LibItemStruct -> Transform[0][1],
			    &LibItemStruct -> Transform[1][0],
			    &LibItemStruct -> Transform[1][1]) != 4)) {
		    Failed = TRUE;
		    break;
		}

		if (!Failed) {
		    LibItemStruct -> Pnext = EEDrawList;
		    EEDrawList = (DrawGenericStruct *) LibItemStruct;
		}
		break;
	    case 'P':				     /* Its a polyline item. */
		PolylineStruct = (DrawPolylineStruct *)
					MyMalloc(sizeof(DrawPolylineStruct));
		PolylineStruct -> StructType = DRAW_POLYLINE_STRUCT_TYPE;
		if (sscanf(&Line[1], "%s %d %d",
			   Name1,
			   &PolylineStruct->Layer,
			   &PolylineStruct -> NumOfPoints) != 3 ||
		    (Name1[0] != 'B' && Name1[0] != 'L')) {
		    sprintf(Line,
			"EEDraw file polyline struct error at line %d, aborted",
								LineCount);
		    Failed = TRUE;
		    break;
		}
		PolylineStruct -> Width =
		    Name1[0] == 'B' ? THICK_WIDTH : NORM_WIDTH;
		PolylineStruct -> Points = (int *) MyMalloc(sizeof(int) * 2 *
						PolylineStruct -> NumOfPoints);
		for (i = 0; i < PolylineStruct -> NumOfPoints; i++) {
		    LineCount++;
		    if (fgets(Line, LINE_LEN - 1, f) == NULL ||
			sscanf(Line, "%d %d", &PolylineStruct -> Points[i*2],
					      &PolylineStruct -> Points[i*2+1])
								!= 2) {
			sprintf(Line,
			 "EEDraw file polyline struct error at line %d, aborted",
								LineCount);
			Failed = TRUE;
			MyFree((VoidPtr) PolylineStruct -> Points);
			break;
		    }
		}

		if (!Failed) {
		    PolylineStruct -> Pnext = EEDrawList;
		    EEDrawList = (DrawGenericStruct *) PolylineStruct;
		}
		break;
	    case 'C':				   /* Its a connection item. */
		ConnectionStruct = (DrawConnectionStruct *)
					MyMalloc(sizeof(DrawConnectionStruct));
		ConnectionStruct -> StructType = DRAW_CONNECTION_STRUCT_TYPE;
		if (sscanf(&Line[1], "%d %d %d",&ConnectionStruct->Layer,
			   &ConnectionStruct -> PosX,
			   &ConnectionStruct -> PosY) != 3) {
		    sprintf(Line,
		      "EEDraw file connection struct error at line %d, aborted",
								LineCount);
		    Failed = TRUE;
		}
		else {
		    ConnectionStruct -> Pnext = EEDrawList;
		    EEDrawList = (DrawGenericStruct *) ConnectionStruct;
		}
		break;
	    case 'T':				   	  /* Its a text item. */
		TextStruct = (DrawTextStruct *) MyMalloc(sizeof(DrawTextStruct));
		TextStruct -> StructType = DRAW_TEXT_STRUCT_TYPE;
		TextStruct -> Scale = 1;	/* seed scale */
		if ((((i = sscanf(&Line[1], "%d %d %d %d %d",
				  &TextStruct->Layer,
			     	  &TextStruct -> PosX,
				  &TextStruct -> PosY,
				  &TextStruct -> Orient,
				  &TextStruct -> Scale)) != 4) && i != 5) ||
		    fgets(Line, LINE_LEN - 1, f) == NULL) {
		    sprintf(Line,
		      "EEDraw file text struct error at line %d, aborted",
								LineCount);
		    Failed = TRUE;
		}
		else {
		    TextStruct -> Text = strdup(strtok(Line, "\n\r"));
		    TextStruct -> Pnext = EEDrawList;
		    EEDrawList = (DrawGenericStruct *) TextStruct;
		}
		if (i == 3) TextStruct -> Scale = 1;  /* No scale specified. */
		break;
	    default:
		Failed = FALSE;
		sprintf(Line, "EEDraw file undef structdef at line %d, aborted",
								LineCount);
		break;
	}

	if (Failed) {
	    FatalError(Line);
	}
    }

    /* EEDrawList was constructed in reverse order - reverse it back: */
    Phead = NULL;
    while (EEDrawList) {
	Pnext = EEDrawList;
	EEDrawList = EEDrawList -> Pnext;
	Pnext -> Pnext = Phead;
	Phead = Pnext;
    }
    EEDrawList = Phead;

    fclose(f);
}
