/* $Id: structure.h,v 1.1.1.1 1996/10/02 10:35:54 roitzsch Exp $ */

#ifndef STRUCTURE_H 
#define STRUCTURE_H

#include "general.h"
#include "stack.h"
#include "matrix.h"
#include "dict.h"


class SMaterial
{
    int	   type;		//  < 0 for holes
    double w[2];   		// x1A, x2A, x1E, x2E;

    friend ostream& operator<<(ostream& s, SMaterial& mat);
    friend class SLayer;
    friend class SSection;
    friend class SSlice;
};
//-------------------------------------------------------------------------


class SLayer 
{
    double  		height[2];
    Stack<SMaterial*>	materials;

    void read (Parser& parser, Dict& matDict, double width);
    friend ostream& operator<< (ostream& os, SLayer& l);

    ~SLayer() { int i; FORALL(materials,i) delete materials[i]; }

    friend class SSlice;
    friend class SSection;
};
//-------------------------------------------------------------------------

class SPoint
{
    int 	classOfSPoint; 
    char 	BC;
    double 	x, y;
    int 	id;

    void init();
    friend ostream& operator<< (ostream& s, SPoint& p);
    friend class SSection;
};

class SBox
{
    enum Type { solid, hole };

    int  classOfSBox, classOfEdge[5], triangRule;
    char BTypeOfEdge[5];
    int  id, node[5];
    Type type;

    void init();
    friend ostream& operator<< (ostream& s, SBox& b);
    friend class SSection;
};


class SSlice
{
    Matrix<double>* x, *y;		// point grid is tensor product x*y

    SSlice()  { x = y = 0; }
    ~SSlice() { delete x; delete y; }

    void init (SSlice& sl);
    void init (int position, Stack<SLayer*>& layers);
    friend ostream& operator<< (ostream& s, SSlice& slice);

    friend class SSection;
};
//-------------------------------------------------------------------------


class SSection
{
    enum          { WORDLENGTH=256 };

    double    	     length, zEnd;
    Stack<SLayer*>   layers;
    SSlice	     sliceA, sliceE, slice;

    Matrix<SBox>*   boxMat;
    Matrix<SPoint>* pointMat;

    int 	    maxPointsX, maxPointsY;

    Stack<char>&    	BCTypes;
    Stack<double>&  	BCValues;
    Dict& 	    	matDict;    


    void read (Parser& parser, double width, double height);

    SSection(Dict& matDict, Stack<char>& BCTypes, Stack<double>& BCValues);

    void pointMatInit();
    void boxMatInit();
    Bool write(char* fileName, double z);
    Bool write (charbuf** cb, double z);
    void fillSlice(double z);
    Bool writeSlice(ostream& out);

  public:
    ~SSection();

    friend class Structure;
};
//-------------------------------------------------------------------------


class Structure
{
  public:

    Real  zEnd; 

    Structure(char* fileName);
    ~Structure();

    Bool write(double z, char* fileName, charbuf** cb = 0);


  private:

    enum 		{ WORDLENGTH=256 };

    char*		strFile;
    char* 		outStream;

    Stack<SSection*> 	sections;

    Dict   		matDict;
    Stack<double>	E, M, P, S;
    Dict	  	paramDict;		// parameters
    Dict	  	factDict;		// factors (units and constants)

    Stack<char>		BCTypes;		// boundary conditions
    Stack<double>	BCValues1;
    Stack<double>	BCValues2;

    int 		infoStructure;

    void read();
    void readMaterial(Parser& parser, Stack<double>& E, Stack<double>& M, 
		      Stack<double>& P, Stack<double>& S);
    Bool writeMatFile (char* fileName);
};

#endif
