/***************************************************************************
 *   Copyright (C) 2004 by Juergen Thies                                   *
 *   layout@juergenthies.de                                                *
 *                                                                         *
 *   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.             *
 ***************************************************************************/
#ifndef OASIS_H
#define OASIS_H

#include <qobject.h>
#include <qstring.h>
#include <qfile.h>
#include "elements/pointarray.h"
#include "elements/propertylist.h"
#include "filegeneral.h"
#include "filewrite.h"
#include <zlib.h>
#include <QHash>
#define zlibBufferSize 1024*64
/**
@author Juergen Thies
*/
class QPoint;

class drawingField;
class errorreport;
class cell;
class cellList;
class fileRead;
enum elementType {boxElement,polygonElement,pathElement,cellrefElement,textElement,circleElement,trapezoidElement,ctrapezoidElement};
class oasis : public QObject
{
Q_OBJECT
public:
    oasis(QObject *parent = 0, const char *name = 0);

    ~oasis();

    static void open(QString filename,drawingField *);
    static void import(QString filename,drawingField *);
    static void update(QString filename,drawingField *);
    static void save(QString filename,drawingField *);
    struct modals {
      bool absoluteMode;
      int placement_x,placement_y,layer,datatype;
      QString placement_cell;
      cell *placementCell;
      double mag,angle;
      bool mirror_x;
      int textlayer,texttype,text_x,text_y;
      QString text_string;
      int geometry_x,geometry_y;
      //int xy_mode;
      int geometry_w, geometry_h;
      pointArray polygon_point_list;
	  pointArray path_point_list;
      int path_halfwidth,path_start_extension,path_end_extension;
      int path_start_extension_value,path_end_extension_value;
      int ctrapezoid_type;
      int circle_radius;
	  QList<propertyItem> last_property_value_list;
      propertyItem last_propertiy_name;
	 
      //  repetition;
      int repetition;
      uint x_dimension,y_dimension,x_space,y_space;
      pointArray repArray;
      int trapezonid_delta_a,trapezonid_delta_b;
      bool  trapezonid_orientation;
    };
	QList<element*> elementListe;
    cellList *cell_list;
    cell *cell_;
    drawingField *drawing_;
    //QString cellNames[4096];
    QStringList cellNames;
    QHash<QString,cell *> cellMap;
    //int cellNameCount;
    //QString textNames[4096];
    //int textNameCount;
    QStringList textNames;
	QStringList propertyNames;
	QStringList propertyStrings;
    modals modal;
    void resetModal();
    void setModalAbsoluteMode();
    void processRepetition(elementType e);
    void addBox();
    void addPolygon();
    void addPath();
    void addText();
    void addCircle();
    void addCellref();
    void addTrapezoid();
    void addCtrapezoid();
    void addElement(elementType e,QPoint p);
    void writeCtrapezoid(int layer, int type, int x, int y, int w, int h,int d);
    void writeTrapezoid(int layer, int type, int x, int y, int w, int h, int da, int db,int d);
    void count();
    void writeSetSimulate();
    void writeSetCompressed();
    void writeEndCompressed();
    uint zlibBeforeSimulated;
    uint zlibAfterSimulated;
private:
    int recordCount;
    drawingField *drawing;
    fileWrite *write;

    fileRead *fread;
    void save(drawingField *, errorreport *report);
    z_stream_s zlib;
    uint zlibBefore,zlibAfter,zlibInPos,zlibOutPos;
    bool zlibUsed;
    bool zlibSimulate;
    quint8 zlibIn[zlibBufferSize],zlibOut[zlibBufferSize];
    void zlibInit(uint before, uint after);
    void zlibSend();
    quint8 zlibReadRaw();
public:  
    void writeString(QString s);
    void writeUnsignedInteger(uint i);
    void writeUnsignedInteger(quint64 i);
    void writeSignedInteger(int i);
    void writeReal(double d);
    void writeRaw(quint8 );
    void writePointArray(pointArray p,bool excludeImplicid);
    void writeGDelta(QPoint p);
    void write1Delta(QPoint p,bool dir);
    void write2Delta(QPoint p);
    void write3Delta(QPoint p);
    errorreport *error;
private:
    QString readString();
    uint readUnsignedInteger();
    quint64 readUnsignedIntegerLong();
    int readSignedInteger();
    void readRepetition();
    double readReal();  
    void  readPointList(bool addImplecid);
    quint8 readRaw();
    QPoint readGDelta();
    QPoint read1Delta(bool dir);
    QPoint read2Delta();
    QPoint read3Delta();
    void readProperty();
    void readExtension();
    int readLayer();
    int getMappedLayer();
    void setPlacementCell(QString cellname);
private:
   static void load(QString filename,drawingField *,  fileOpenType type);
   void load(fileRead *fr, drawingField *, errorreport *error);

};

#endif
