/***************************************************************************
 *   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.             *
 ***************************************************************************/
#include "oasis.h"
#include <qfile.h>
#include <qdatetime.h>
//Added by qt3to4:
#include "elements/pointarray.h"
#include "general/drawingfield.h"
#include <math.h>
#include "layout.h"
#include "general/errorreport.h"
#include "general/setup.h"
#include "general/layers.h"
#ifndef multithread
#include "file_read.h"
#else
#include "threads/fileread.h"
#endif
#include <qmessagebox.h>

#define NONEXISTINGCELL "layout#cell~"
#define NONEXISTINGPROP "layout#prop~"
//#define NONEXISTINGCELL "~"

oasis::oasis(QObject *parent, const char *)
 : QObject(parent)
{
}


oasis::~oasis()
{

}

void oasis::open(QString fileName,drawingField *d){
  load(fileName,d,fileOpen);
}

void oasis::import(QString fileName,drawingField *d){
  load(fileName,d,fileImport);
}

void oasis::update(QString fileName,drawingField *d){
  load(fileName,d,fileUpdate);
}

void oasis::load(QString fileName,drawingField *d,fileOpenType typ){
  errorreport report;
  QString s;
  if (typ==fileImport) {
  	report.setTitle(tr("Import of OASIS-File \"")+fileName+"\"");}
  else if (typ==fileOpen){
	report.setTitle(tr("Open of OASIS-File \"")+fileName+"\"");}
  else if (typ==fileUpdate){
	report.setTitle(tr("Update with OASIS-File \"")+fileName+"\"");}
try { 
  cellList *firstcellhelp=d->firstCell;
  double databaseunitshelp=d->databaseunits;
 if (setup::oasisAutoMapDatatypes) {
	setup::oasisMapLayer=true;
	if ((typ==fileImport)||(typ==fileUpdate)) layers::generateLayerAutoMap(d);
	else layers::generateLayerAutoMap(NULL);
	}
  else if (setup::oasisMapLayer) layers::generateLayerMap();
  //QFile f( fileName );
  fileRead f(fileName);
  if ( f.open(  ) ) { //QIODevice::ReadOnly
        throw QString(tr("Can not open File."));}
  //QDataStream ts( &f );
  if ((typ==fileImport)||(typ==fileUpdate)) {
	d->firstCell=NULL;
  } 
  oasis oasisClass;
  oasisClass.load(&f,d,&report);
  f.close();
  filegeneral::resolveBrockenCellrefs(&report,d,firstcellhelp,typ);
  //printf("o2: %d ms\n", setup::centralTimer.elapsed());
  d->currentCell=d->findTopCell();
  //printf("o3: %d ms\n", setup::centralTimer.elapsed());
  if (d->currentCell==NULL) d->currentCell=d->firstCell->thisCell;
  if ((typ==fileImport)||(typ==fileUpdate)) filegeneral::fitDifferentDatabaseunits(&report,d,databaseunitshelp);
  if (typ==fileImport) filegeneral::import(&report,d,firstcellhelp);
  if (typ==fileUpdate) filegeneral::update(&report,d,firstcellhelp);
 } //end try
 catch (QString s){
  report.addItem(tr("Aborted. "),0);
  report.addItem(s,1);
 }
  //report.showReport(); 
  s=report.getReport();
  d->showReport(s,report.getLastRang());
}

void oasis::load(fileRead *fr, drawingField *drawing, errorreport *report){
  error=report;
  //streamPtr=stream;
  fread=fr;
  QString s,s1;
  quint8 help;
  uint i,k;
#ifdef printtime
  setup::centralTimer.start();
#endif
  QTime oasisTimer;
  oasisTimer.start();
  s1="";
  zlibUsed=false;
  for (i=0;i<13;i++){
  	help=readRaw(); 
	if (help!=0){
		s=help; 
		s1+=s;}
	}
  if (s1!="%SEMI-OASIS\r\n") throw QString(tr("invalid Format."));
  uint record=0;
  bool tableAtEnd=false;
  cell_=NULL;
  drawing_ =drawing;
  quint8 info_byte;
  //int cellNameCount=0;
  //int textNameCount=0;
  uint recordCount=0;
  elementListe.clear();
  do {
  	record=readUnsignedInteger();
	//printf("record: %d\n",record);
	switch (record){
	case 0: //pad
		if (layout::debug) printf("pad\n");
		break;
	case 1: //start
		if (layout::debug) printf("start\n");
		s=readString();
		if (s!="1.0") throw QString(tr("Unknown/unsupportet version of OASIS: ")+s);
		drawing->fileType="OASIS version 1.0";
		drawing->databaseunits=(double)(0.000001)/readReal();
		{QString sh;
		sh.setNum(drawing->databaseunits);
		drawing->databaseunits=sh.toDouble();}
		if (layout::debug) printf("drawingunits: %f\n",drawing->databaseunits);
		i=readUnsignedInteger();
		if (i==0) {
			tableAtEnd=false;
			for (i=0;i<12;i++)k=readUnsignedInteger();}
		else tableAtEnd=true;
		break;
	case 2: //end
		if (layout::debug) printf("end\n");
		if (tableAtEnd) {for (i=0;i<12;i++)k=readUnsignedInteger();}
		//s=readString();
		//i=readUnsignedInteger();
		break;
	case 3: //cellname
		cellNames<<readString();
		if (layout::debug) printf("cellname %s\n",cellNames.last().toAscii().constData());
		//cellNameCount++;
		break;
	case 4: //cellname
		s=readString();
		i=readUnsignedInteger();
		while (i>=(uint)(cellNames.size())) cellNames<<"";
		cellNames[i]=s;
		if (layout::debug) printf("cellname %s %d\n",cellNames[i].toAscii().constData(),i);
		break;
	case 5: //textname
		textNames<<readString();
		if (layout::debug) printf("textname #%d %s\n",textNames.size()-1,textNames.last().toAscii().constData());
		//textNameCount++;
		break;
	case 6: //textname
		s=readString();
		i=readUnsignedInteger();
		while (i>=(uint)(textNames.size())) textNames<<"";
		textNames[i]=s;
		if (layout::debug) printf("textname %s %d\n",textNames[i].toAscii().constData(),i);
		break;
	case 7: //property
		propertyNames<<readString();
		if (layout::debug) printf("property %s\n",propertyNames.last().toAscii().constData());
		break;
	case 8: //property
		s=readString();
		i=readUnsignedInteger();
		while (i>=(uint)(propertyNames.size())) propertyNames<<"";
		propertyNames[i]=s;
		if (layout::debug) printf("property %s %d\n",s.toAscii().constData(),i);
		break;
	case 9: //property string
		propertyStrings<<readString();
		if (layout::debug) printf("propstring %s\n",propertyStrings.last().toAscii().constData());
		break;
	case 10: //property string
		s=readString();
		i=readUnsignedInteger();
		while (i>=(uint)(propertyStrings.size())) propertyStrings<<"";
		propertyStrings[i]=s;
		if (layout::debug) printf("propstring %s %d\n",s.toAscii().constData(),i);
		break;
	case 11: //layername textlayername 
	case 12:
		s=readString();
		if (layout::debug) printf("layer/textlayer %s\n",s.toAscii().constData());
		i=readUnsignedInteger();
		switch (i) {
		case 0:
			for (int n=0;n<layersMax;n++){
				layers::num[n].name=s;}
			break;
		case 1: i=readUnsignedInteger();
			for (int n=0;n<=(int)i;n++){
				layers::num[n].name=s;}
			break;
		case 3: 
			i=readUnsignedInteger();
			layers::num[i].name=s;
			break;
		case 2: 
			i=readUnsignedInteger();
			for (int n=i;n<layersMax;n++){
				layers::num[n].name=s;}
			break;
		case 4: i=readUnsignedInteger();
			k=readUnsignedInteger();
			for (int n=i;n<(int)k;n++){
				layers::num[n].name=s;}
			break;
		default:
			report->addItem(tr("Error in layername/textlayername"),2);
		};
		//datatype
		i=readUnsignedInteger();
		switch (i) {
		case 0:
			break;
		case 1: i=readUnsignedInteger();
			break;
		case 2: 
			i=readUnsignedInteger();
			break;
		case 3: 
			i=readUnsignedInteger();
			break;
		case 4: i=readUnsignedInteger();
			k=readUnsignedInteger();
			break;
		default:
			report->addItem(tr("Error in layername/textlayername"),2);
		};
		break;
	case 13: // cellrecord 
		{ 
		cell_list=drawing->addCell();
		cell_=cell_list->this_cell;
		i=readUnsignedInteger();
		QString cn="";
		if (i>=(uint)(cellNames.size())) {
			cn=NONEXISTINGCELL+s.setNum(i);
			cell_->cellName=cn;
			}
		else {
			cell_->cellName=cellNames[i];
			cn=cell_->cellName;
			cellMap[NONEXISTINGCELL+s.setNum(i)]=cell_;
			}
		cellMap[cn]=cell_;
		if (layout::debug) printf("cell by num %s\n",cell_->cellName.toAscii().constData());
		resetModal();
		}
		break;
	case 14: // cellrecord
		cell_list=drawing->addCell();
		cell_=cell_list->this_cell;
		cell_->cellName=readString();
		cellMap[cell_->cellName]=cell_;
		if (layout::debug) printf("cell %s\n",cell_->cellName.toAscii().constData());
		resetModal();
		break;
	case 15: //xyabsolute
		if (layout::debug) printf("absolut mode\n");
		modal.absoluteMode=true;
		break;
	case 16: //xyrelative
		if (layout::debug) printf("relative mode\n");
		modal.absoluteMode=false;
		break;
	case 17: //cellref
		if (layout::debug) printf("cellref\n");
		modal.mag=1;
		modal.angle=0;
		modal.mirror_x=false;
		info_byte=readRaw();
		if (layout::debug) printf("cellref (17) %d\n",info_byte);
		if (info_byte&128) {
			if (info_byte&64){i=readUnsignedInteger();
					QString cn="";
					if (i>=(uint)(cellNames.size())) cn=NONEXISTINGCELL+s.setNum(i);
					else cn=cellNames[i];
					setPlacementCell(cn);}
			else setPlacementCell(readString());
			}
		if (layout::debug) printf("cellref name:%s\n",modal.placement_cell.toAscii().constData());
		if (info_byte&1) modal.mirror_x=true;
		if ((info_byte&6)==2) modal.angle=90;
		if ((info_byte&6)==4) modal.angle=180;
		if ((info_byte&6)==6) modal.angle=270;
		if ((modal.angle!=0)&&modal.mirror_x) modal.angle=360-modal.angle;
		if (modal.absoluteMode) {
			if (info_byte&32) modal.placement_x=readSignedInteger();
			if (info_byte&16) modal.placement_y=readSignedInteger();}
		else {
			if (info_byte&32) modal.placement_x+=readSignedInteger();
			if (info_byte&16) modal.placement_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&8) { 
			readRepetition();
			processRepetition(cellrefElement);}
		else addCellref();
		break;
	case 18: //cellref
		modal.mag=1;
		modal.angle=0;
		modal.mirror_x=false;
		info_byte=readRaw();
		if (layout::debug) printf("cellref (18) %d\n",info_byte);
		if (info_byte&128) {
			if (info_byte&64){i=readUnsignedInteger();
					QString cn="";
					if (i>=(uint)(cellNames.size())) cn=NONEXISTINGCELL+s.setNum(i);
					else cn=cellNames[i];
					setPlacementCell(cn);}
			else setPlacementCell(readString());
			}
		if (layout::debug) printf("cellref name:%s\n",modal.placement_cell.toAscii().constData());
		if (info_byte&1) modal.mirror_x=true;
		if (info_byte&4) modal.mag=readReal();
		if (info_byte&2) modal.angle=readReal();
		if ((modal.angle!=0)&&modal.mirror_x) modal.angle=360-modal.angle;
		if (modal.absoluteMode) {
			if (info_byte&32) modal.placement_x=readSignedInteger();
			if (info_byte&16) modal.placement_y=readSignedInteger();}
		else {
			if (info_byte&32) modal.placement_x+=readSignedInteger();
			if (info_byte&16) modal.placement_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&8) { 
			readRepetition();
			processRepetition(cellrefElement);}
		else addCellref();
		break;
	case 19: //text
		if (layout::debug) printf("text\n");
		info_byte=readRaw();
		if (info_byte&64) {
			if (info_byte&32){i=readUnsignedInteger();
			//printf("insert text nr: %d\n",i);
					while (i>=(uint)(textNames.size())) textNames<<"";
					if (textNames[i]=="")textNames[i]="layout#text~"+s.setNum(i);
					modal.text_string=textNames[i];}
			else modal.text_string=readString();
			}
		if (info_byte&1) modal.textlayer=readLayer();
		if (info_byte&2) modal.texttype=readUnsignedInteger();
		if (modal.absoluteMode) {
			if (info_byte&16) modal.text_x=readSignedInteger();
			if (info_byte&8) modal.text_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.text_x+=readSignedInteger();
			if (info_byte&8) modal.text_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(textElement);}
		else addText();
		break;
	case 20: //rectangle/box
		if (layout::debug) printf("box\n");
		info_byte=readRaw();
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		if (info_byte&64) modal.geometry_w=readUnsignedInteger();
		if (info_byte&32) modal.geometry_h=readUnsignedInteger();
		if (info_byte&128) modal.geometry_h=modal.geometry_w;
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(boxElement);}
		else addBox();
		break;
	case 21: //polygon
		if (layout::debug) printf("polygon\n");
		info_byte=readRaw();
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		if (info_byte&32) readPointList(true);
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(polygonElement);}
		else addPolygon();
		break;
	case 22: //path
		if (layout::debug) printf("path\n");
		info_byte=readRaw();
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		if (info_byte&64) modal.path_halfwidth=readUnsignedInteger();
		if (info_byte&128) readExtension();
		if (info_byte&32) {
			pointArray ph=modal.polygon_point_list;
			readPointList(false);
			modal.path_point_list=modal.polygon_point_list;
			modal.polygon_point_list=ph;
			}
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(pathElement);}
		else addPath();
		break;
	case 23: //trapezonid
		if (layout::debug) printf("trapezoid\n");
		modal.trapezonid_delta_a=0;
		modal.trapezonid_delta_b=0;
		modal.trapezonid_orientation=false;
		info_byte=readRaw();
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		if (info_byte&64) modal.geometry_w=readUnsignedInteger();
		if (info_byte&32) modal.geometry_h=readUnsignedInteger();
		if (info_byte&128) modal.trapezonid_orientation=true;
		modal.trapezonid_delta_a=read1Delta(false).x();
		modal.trapezonid_delta_b=read1Delta(false).x();
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(trapezoidElement);}
		else {addTrapezoid();};
		break;
	case 24:
	case 25:
		if (layout::debug) printf("trapezoid\n");
		info_byte=readRaw();
		modal.trapezonid_delta_a=0;
		modal.trapezonid_delta_b=0;
		modal.trapezonid_orientation=false;
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		if (info_byte&64) modal.geometry_w=readUnsignedInteger();
		if (info_byte&32) modal.geometry_h=readUnsignedInteger();
		if (info_byte&128) modal.trapezonid_orientation=true;
		if (record==24) modal.trapezonid_delta_a=read1Delta(false).x();
		else modal.trapezonid_delta_b=read1Delta(false).x();
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(trapezoidElement);
			}
		else {addTrapezoid();};
		break;
	case 26:
		if (layout::debug) printf("ctrapezoid\n");
		info_byte=readRaw();
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		if (info_byte&128) modal.ctrapezoid_type=readUnsignedInteger();
		if (info_byte&64) modal.geometry_w=readUnsignedInteger();
		if (info_byte&32) modal.geometry_h=readUnsignedInteger();
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		{int type=modal.ctrapezoid_type;
  		if ((type==16)||(type==17)||(type==18)||(type==19)||(type==25)) modal.geometry_h=modal.geometry_w;
  		if ((type==20)||(type==21)) modal.geometry_w=2*modal.geometry_h;
  		if ((type==22)||(type==23)) modal.geometry_h=2*modal.geometry_w;}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(ctrapezoidElement);
			}
		else {addCtrapezoid();};
		break;
	case 27:
		if (layout::debug) printf("circle\n");
		info_byte=readRaw();
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		if (info_byte&32) modal.circle_radius=readUnsignedInteger();
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		elementListe.clear();
		if (info_byte&4) { 
			readRepetition();
			processRepetition(circleElement);
			}
		else {addCircle();};
		break;
	case 28: //property
		modal.last_property_value_list.clear();
		//QList<propertyItem> last_property_value_list;
		//propertyItem last_propertiy_name;
		info_byte=readRaw();
		if (layout::debug) printf("property %d\n",info_byte);
		if ((info_byte&4)&&(info_byte&2)) {
			int num=readUnsignedInteger();
			//printf("num %d\n",num);
			if (num>=(int)(propertyNames.size())) {QString s;
			    modal.last_propertiy_name=NONEXISTINGPROP+s.setNum(num);}
			else    if (propertyNames[num]=="") modal.last_propertiy_name=propertyItem(num);
			else	modal.last_propertiy_name=propertyItem(propertyNames[num]);
		}
		else if ((info_byte&4)&&(!(info_byte&2))) modal.last_propertiy_name=propertyItem(readString());
		if ((info_byte&8)==0) {
			int count=info_byte>>4;
			if (count==15) count= readUnsignedInteger();
			//printf("count %d\n",count);
			for (int i=0; i<count; i++){
				readProperty();
				}
			}
		else {
			modal.last_property_value_list<<modal.last_propertiy_name;
		}
		//break;
	case 29: //property-repeat
		if (layout::debug) printf("property repeat\n");
		for (int i=0;i<elementListe.size();i++){
			elementListe[i]->addProperty(modal.last_property_value_list);
		}
		;
		break;
	case 30: //Xname record
		readUnsignedInteger();
		readString();
		readUnsignedInteger();
		break;
	case 31: //Xname record
		readUnsignedInteger();
		readString();
		break;
	case 32: //Xelement record
		readUnsignedInteger();
		readString();
		break;
	case 33: //xgeometry record
		info_byte=readRaw();
		readUnsignedInteger();
		if (info_byte&1) modal.layer=readLayer();
		if (info_byte&2) modal.datatype=readUnsignedInteger();
		readString();
		if (info_byte&32) modal.circle_radius=readUnsignedInteger();
		if (modal.absoluteMode) {
			if (info_byte&16) modal.geometry_x=readSignedInteger();
			if (info_byte&8) modal.geometry_y=readSignedInteger();}
		else {
			if (info_byte&16) modal.geometry_x+=readSignedInteger();
			if (info_byte&8) modal.geometry_y+=readSignedInteger();
		}
		if (info_byte&4) { 
			readRepetition();
			}
		break;
	case 34: //compression
		{
		int type=readUnsignedInteger();
		if (layout::debug) printf("compressed type: %d \n",type);;
		uint before=readUnsignedInteger();
		uint after=readUnsignedInteger();
		if (layout::debug) printf("compressed: %d/%d \n",before,after);
		zlibInit(after,before);
		}
		break;
	default: 
		throw QString(tr("Unknown/unsupported Record.")+s.setNum(record));
	}
  recordCount++;
  if (((recordCount%5000)==0)||(record==2) ){
		QString sh;
		sh.setNum(recordCount);
		if ((record==2)||(oasisTimer.elapsed()>200)){
		drawing->showMessage(tr("%1 elements loaded.").arg(sh));
		oasisTimer.start();
		}
		}
  }
  while (record!=2);


#ifdef printtime
  printf("oasis load: %d ms\n", setup::centralTimer.elapsed());
#endif
 int lhelp=QString(NONEXISTINGCELL).length();
 int phelp=QString(NONEXISTINGPROP).length();
  // update cellref/text, if table at end
 for (cellList *f =drawing->firstCell; f!=NULL;f=f->nextCell) {
  	if (f->thisCell!=NULL){
			QString s1=f->thisCell->cellName;
			if (s1.left(lhelp)==NONEXISTINGCELL){
				s1=s1.mid(lhelp);
				cellMap[cellNames[s1.toInt()]]=cellMap.value(f->thisCell->cellName,NULL);
				f->thisCell->cellName=cellNames[s1.toInt()];
				//printf("%d,%s,%s\n",lhelp,f->thisCell->cellName.toAscii().data(),cellNames[s1.toInt()].toAscii().data());
			};
		}
	}
#ifdef printtime
  //printf("oasis load (2): %d ms\n", setup::centralTimer.elapsed());
#endif
 for (cellList *f =drawing->firstCell; f!=NULL;f=f->nextCell) {
 	if (f->this_cell!=NULL){
  		for (elementList *e=f->thisCell->firstElement;e!=NULL;e=e->nextElement){
			if (e->thisElement->isCellref()||e->thisElement->isCellrefArray()) {
				 if (e->thisElement->depend()==NULL){
				 	//QString s1=e->thisElement->getName();
					//if (s1.left(lhelp)==NONEXISTINGCELL)
						{
						//s1=s1.mid(lhelp);
						//e->thisElement->setName(QString(""));//cellNames[s1.toInt()]);
						//printf("%s\n",cellNames[s1.toInt()].toAscii().data());
						e->thisElement->setCellRef(cellMap.value(e->thisElement->getName(),NULL));
						if (e->thisElement->getName().left(lhelp)==NONEXISTINGCELL) e->thisElement->setName(QString(""));
						//e->thisElement->setCellRef(drawing->findCell(cellNames[s1.toInt()]));
						};
					}}
			if (e->thisElement->isText()){
				QString s1=e->thisElement->getName();
				if (s1.left(12)=="layout#text~"){
					QString s2=s1.mid(12);
					if (textNames[s2.toInt()]==s1) report->addItem(tr("Text lable is missing."),2);
					e->thisElement->setName(textNames[s2.toInt()]);
					};
				};
			if (e->thisElement!=NULL){
			  int i=e->thisElement->property.size();
			  for (int k=0;k<i;k++){
			    if (e->thisElement->property.at(k).getString().left(phelp)==QString(NONEXISTINGPROP)){
			      QString s1=e->thisElement->property.at(k).getString().mid(lhelp);
			      e->thisElement->property[k].setName(propertyNames[s1.toInt()]);}
			    if (e->thisElement->property.at(k).getValueString().left(phelp)==QString(NONEXISTINGPROP)){
			      QString s1=e->thisElement->property.at(k).getValueString().mid(lhelp);
			      e->thisElement->property[k].setValue(propertyStrings[s1.toInt()]);
			    }
			  }
			}
			}
		f->thisCell->clean();
		}
	}
#ifdef printtime
  //printf("oasis load(3): %d ms\n", setup::centralTimer.elapsed());
#endif
}

void oasis::save(QString fileName,drawingField *d){
errorreport report;
report.setTitle(tr("Save of OASIS-File \"")+fileName+"\"");
try { 
  
  oasis oasisClass;
  oasisClass.write=new fileWrite(fileName);
  if ( !oasisClass.write->open() ) {
	throw QString(tr("Can not open File."));
  }
  oasisClass.save(d,&report);
  oasisClass.write->close();
  delete oasisClass.write;
  
}
catch (QString s){
  report.addItem(tr("Aborted. "),0);
  report.addItem(s,1);
 }
  //report.showReport();   
  QString s=report.getReport();
  d->showReport(s,report.getLastRang());

}
 
void oasis::save(drawingField *d, errorreport *report){
drawing=d;
recordCount=0;
zlibUsed=false;
zlibSimulate=false;
error=report;
//magic bytes
write->writeString(QString("%SEMI-OASIS"),QString("%SEMI-OASIS").length());
write->writeUInt8(13);
write->writeUInt8(10);
//(*streamPtr)<<(quint8)13<<(quint8)10;
// start record
  writeUnsignedInteger((uint)1);
  writeString(QString("1.0"));
  writeReal((double)0.000001/d->databaseunits);
  writeUnsignedInteger((uint)1);
 
  cellList *e;
  for(e=d->firstCell;e!=NULL;e=e->nextCell){
	e->thisCell->saved=false;}
  bool saved=false;
  while (!saved){
	saved=true;
	for(e=d->firstCell;e!=NULL;e=e->nextCell){
		if (e->thisCell->saved==false){
			if (!e->thisCell->dependNotSaved()){resetModal();e->thisCell->saveOASIS(this);}
			else{saved=false;}};
		}}
  
// end record
  writeUnsignedInteger((uint)2);
  // table-offset -> no tables
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  writeUnsignedInteger((uint)0);
  //padding-string
  QString s="";
  for (int i=0; i<240;i++) {s=s+" ";}
  writeString(s);
  //validation (off)
  writeUnsignedInteger((uint)0);
}

void oasis::writePointArray(pointArray p,bool excludeImplicid){
  bool type0=true;
  bool type1=true;
  bool type2=true;
  bool type3=true;
 int i;
  if ((p.size())%2==0) {
		type0=false;
		type1=false;}
  if (p.size()<4) {
		type0=false;
		type1=false;}
  for (i=0;i<p.size()-1;i++){
  	QPoint pd=p.point(i+1)-p.point(i);
  	if ((pd.y()!=0) &&(i%2!=0)) type1=false;
	if ((pd.x()!=0) &&(i%2!=0)) type0=false;
	if ((pd.x()!=0) &&(i%2!=1)) type1=false;
	if ((pd.y()!=0) &&(i%2!=1)) type0=false;
	if ((pd.x()!=0) && (pd.y()!=0)) type2=false;
	if ((pd.x()!=0)&&(pd.y()!=0)&&(pd.x()!=pd.y())&&(pd.x()!=-pd.y())) type3=false;
  }
  if (type0) {
	 if (layout::debug)	
		printf("save polygon type 0 \n");
	writeUnsignedInteger((uint)0);
  	int count=0;
  	if (excludeImplicid) count=p.size()-3;
 	else count=p.size()-1;
 	writeUnsignedInteger((uint)count);
 	QPoint last=p.point(0);
 	for (int i=1;i<=count;i++)
 	 	{
		write1Delta(p.point(i)-last,i%2==0);
		QPoint h=p.point(i)-last;
		last=p.point(i);
  		}
	}
  else if (type1) {
	 if (layout::debug)	
		printf("save polygon type 1 \n");
	writeUnsignedInteger((uint)1);
  	int count=0;
  	if (excludeImplicid) count=p.size()-3;
 	else count=p.size()-1;
 	writeUnsignedInteger((uint)count);
 	QPoint last=p.point(0);
 	for (int i=1;i<=count;i++)
 	 	{
		write1Delta(p.point(i)-last,i%2==1);
		QPoint h=p.point(i)-last;
		last=p.point(i);
  		}
	}
  else if (type2) {
	 if (layout::debug)	
		printf("save polygon type 2 \n");
	writeUnsignedInteger((uint)2);
  	int count=0;
  	if (excludeImplicid) count=p.size()-2;
 	else count=p.size()-1;
 	writeUnsignedInteger((uint)count);
 	QPoint last=p.point(0);
 	for (int i=1;i<=count;i++)
 	 	{
		write2Delta(p.point(i)-last);
		QPoint h=p.point(i)-last;
		last=p.point(i);
  		}
	}
  else if (type3) {
	 if (layout::debug)	
		printf("save polygon type 3 \n");
	writeUnsignedInteger((uint)3);
  	int count=0;
  	if (excludeImplicid) count=p.size()-2;
 	else count=p.size()-1;
 	writeUnsignedInteger((uint)count);
 	QPoint last=p.point(0);
 	for (int i=1;i<=count;i++)
 	 	{
		write3Delta(p.point(i)-last);
		QPoint h=p.point(i)-last;
		last=p.point(i);
  		}
	}
  else {
	 if (layout::debug)	
		printf("save polygon type 4 \n");
  	writeUnsignedInteger((uint)4);
  	int count=0;
  	if (excludeImplicid) count=p.size()-2;
 	else count=p.size()-1;
 	writeUnsignedInteger((uint)count);
 	QPoint last=p.point(0);
 	for (int i=1;i<=count;i++)
 	 	{
		writeGDelta(p.point(i)-last);
		QPoint h=p.point(i)-last;
		last=p.point(i);
  		}
	}
}
    
void oasis::write1Delta(QPoint p,bool dir){
  qint64 w;
  if (dir) w=p.y();
  else w=p.x();
  if (w>0) w=(w<<1);
  else w=((-w)<<1)+1;
  writeUnsignedInteger((quint64)w);
  //printf("w: %d\n",w);
}


void oasis::write2Delta(QPoint p){
 qint64 w;
 if (p.x()==0) {
   if (p.y()>0) w=((qint64)(p.y())<<2)+1;
   else w=((qint64)(-p.y())<<2)+3;
 }
 else {
   if (p.x()>0) w=((qint64)(p.x())<<2)+0;
   else w=((qint64)(-p.x())<<2)+2;
 }
 writeUnsignedInteger((quint64)w);
}

void oasis::write3Delta(QPoint p){
qint64 w;
 if (p.x()==0){
   if (p.y()>0) w=((qint64)(p.y())<<3)+1;
   else w=((qint64)(-p.y())<<3)+3;
 }
 else if (p.y()==0) {
   if (p.x()>0) w=((qint64)(p.x())<<3)+0;
   else w=((qint64)(-p.x())<<3)+2;
 }
 else if (p.y()==p.x()) {
   if (p.y()>0) w=((qint64)(p.y())<<3)+4;
   else w=((qint64)(-p.y())<<3)+6;
 }
 else {
   if (p.x()>0) w=((qint64)(p.x())<<3)+7;
   else w=((qint64)(-p.x())<<3)+5;
 }
 writeUnsignedInteger((quint64)w);
//printf("w: %d\n",w);
}

void oasis::writeGDelta(QPoint p){
  if ((p.y()==0)){
  	qint64 i=0;
  	if (p.x()>=0) {i=0;i=((qint64)(p.x())<<4)+2*i;}
	else {i=2;i=((qint64)(-p.x())<<4)+2*i;}
	writeUnsignedInteger((quint64)i);}
  else if (p.x()==0) {
  	qint64 i=0;
  	if (p.y()>=0) {i=1;i=((qint64)(p.y())<<4)+2*i;}
	else {i=3;i=((qint64)(-p.y())<<4)+2*i;}
	writeUnsignedInteger((quint64)i);}
  else if (p.y()==p.x()){
  	qint64 i=0;
  	if (p.x()>=0) {i=4;i=((qint64)(p.x())<<4)+2*i;}
	else {i=6;i=((qint64)(-p.x())<<4)+2*i;}
	writeUnsignedInteger((quint64)i);}
  else if (p.y()==-p.x()){
  	qint64 i=0;
  	if (p.x()>=0) {i=7;i=((qint64)(p.x())<<4)+2*i;}
	else {i=5;i=((qint64)(-p.x())<<4)+2*i;}
	writeUnsignedInteger((quint64)i);}
  else {
  	qint64 i=0,k=0,j=0;
  	if (p.x()<=0) {i=2;k=((qint64)(-p.x())<<2)+i+1;}
	else k=((qint64)(p.x())<<2)+i+1;
	writeUnsignedInteger((quint64)k);
	if (p.y()<=0) {j=1;k=((qint64)(-p.y())<<1)+j;}
	else k=((qint64)(p.y())<<1)+j;
	writeUnsignedInteger((quint64)k);
	}
}

void oasis::writeString(QString s){
 if (layout::debug) printf("string: %s\n",s.toAscii().constData());
 writeUnsignedInteger((uint)s.length());
 if (zlibUsed) {
	const char *a=s.toAscii().constData();
	for (int i=0;i<s.length();i++){
		writeRaw((quint8)(*a++));
	}
	}
 else write->writeString(s,s.length());
}

void oasis::writeUnsignedInteger(uint i){
if (layout::debug) printf("uint: %u\n",i);
  while (i>127) {
  	uint h=i&(127);
  	i=i>>7;
  	h+=128;
  	writeRaw((quint8)(h));
  }
  writeRaw((quint8)(i));
}

void oasis::writeUnsignedInteger(quint64 i){
if (layout::debug) printf("quint64: %llu\n",i);
  while (i>(quint64)(127)) {
  	quint64 h=i&(127);
  	i=i>>7;
  	h+=128;
  	writeRaw((quint8)(h));
  }
  writeRaw((quint8)(i));
}

void oasis::writeSignedInteger(int i){
if (layout::debug) printf("int: %d\n",i);
 bool sig=false;
 if (i<0) sig=true;
 i=abs(i);
 int h=(i&(63))<<1;
 i=i>>6;
 if (sig) h++;
 while (i!=0) {
 	h+=128;
 	writeRaw((quint8)(h));
	h=i&(127);
  	i=i>>7;
 }
 writeRaw((quint8)(h));
}


void oasis::writeReal(double d){
if (layout::debug) printf("real: %f\n",d);
 if (((d-(double)(element::round(d)))<0.00000000001)&&(((d-(double)(element::round(d)))>-0.00000000001))){
  	if (d>=0) {
	writeUnsignedInteger((uint)0);
	writeUnsignedInteger((uint)element::round(d));
  	}
  	else {
	writeUnsignedInteger((uint)1);
	writeUnsignedInteger((uint)element::round(-d));
	}
 }
 else if ((((1.0/d)-(double)(element::round(1.0/d)))<0.00000000001)&&((((1.0/d)-(double)(element::round(1.0/d)))>-0.00000000001))) {
  	if ((1.0/d)>=0) {
	writeUnsignedInteger((uint)2);
	writeUnsignedInteger((uint)element::round(1/d));
  	}
	else {
	writeUnsignedInteger((uint)3);
	writeUnsignedInteger((uint)element::round(-1/d));
  	}
 }
 else {
  writeUnsignedInteger((uint)7);
 	union {
		double dhelp;
		quint8 a[8];};
	dhelp=d;
	for (uint z=0;z<8;z++){writeRaw((quint8)(a[z]));}
  //(*streamPtr)<<d;
  }
}
 
void oasis::writeRaw(quint8 c){
if (zlibUsed){
	zlibBefore++;
	zlibIn[zlibInPos]=c;
	zlibInPos++;
	zlib.avail_in++;
	if ( zlib.avail_in==zlibBufferSize){
		bool force=false;
		int r=0;
		uint last=zlib.avail_in;
		//printf("write\n");
		while (zlib.avail_in>0){
			if (!force) r=deflate(&zlib,Z_NO_FLUSH); 
			else r=deflate(&zlib,Z_SYNC_FLUSH); 
			if (zlib.avail_in==last) force=true;
			zlibAfter+=zlibBufferSize-zlib.avail_out;
			if (!zlibSimulate){
				for (uint i=0;i<zlibBufferSize-zlib.avail_out;i++){
					write->writeUInt8(zlibOut[i]);
				}
				//printf("wrote compressed %d left data %d in %d (error %d)\n",zlibBufferSize-zlib.avail_out,zlib.avail_in, zlibInPos,r);
			}
			zlib.avail_out=zlibBufferSize;
			zlib.next_out=(quint8 *)&zlibOut[0];
			last=zlib.avail_in;
		}
		zlibInPos=0;
		zlib.next_in=(quint8 *)&zlibIn[0];
		zlib.avail_in=0;
			
		

	}
 //printf("raw: %d\n",(uint)(c));
 // no writeRaw in writeString
 // (*streamPtr)<<c;
}
else write->writeUInt8(c);
}

void oasis::readPointList(bool addImplecid){
  int type=readUnsignedInteger();
  int count=readUnsignedInteger();
  modal.polygon_point_list.resize(count+1);
  modal.polygon_point_list.setPoint(0,0,0);
  QPoint last=QPoint(0,0);
  int i;
  bool dir=true;
 if (layout::debug) printf("pointlist type %d\n",type);
 if (layout::debug) printf("pointlist count %d\n",count);
  switch (type){
  case 0: 
  	dir=false;
	for (i=1;i<=count;i++){
		last+=read1Delta(dir);
		modal.polygon_point_list.setPoint(i,last);
		dir=!dir;
		}
	if (addImplecid) {
		modal.polygon_point_list.resize(modal.polygon_point_list.size()+2);
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-2,0,modal.polygon_point_list.point(modal.polygon_point_list.size()-3).y());
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-1,modal.polygon_point_list.point(0));
	}
	break;
  case 1: 
  	for (i=1;i<=count;i++){
		last+=read1Delta(dir);
		modal.polygon_point_list.setPoint(i,last);
		dir=!dir;
		}
	if (addImplecid) {
		modal.polygon_point_list.resize(modal.polygon_point_list.size()+2);
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-2,modal.polygon_point_list.point(modal.polygon_point_list.size()-3).x(),0);
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-1,modal.polygon_point_list.point(0));
	}
	break;
  case 2: 
  	for (i=1;i<=count;i++){
		last+=read2Delta();
		modal.polygon_point_list.setPoint(i,last);
		}
	if (addImplecid) {
		modal.polygon_point_list.resize(modal.polygon_point_list.size()+1);
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-1,modal.polygon_point_list.point(0));
	}
	break;
  case 3: 
  	for (i=1;i<=count;i++){
		last+=read3Delta();
		modal.polygon_point_list.setPoint(i,last);
		}
	if (addImplecid) {
		modal.polygon_point_list.resize(modal.polygon_point_list.size()+1);
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-1,modal.polygon_point_list.point(0));
	}
	break;
  case 4:
  	for (i=1;i<=count;i++){
		last+=readGDelta();
		modal.polygon_point_list.setPoint(i,last);}
	if (addImplecid) {
		modal.polygon_point_list.resize(modal.polygon_point_list.size()+1);
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-1,modal.polygon_point_list.point(0));
	}
  	break;
  case 5: 
  	{
	QPoint l=QPoint(0,0);
        for (i=1;i<=count;i++){
		last+=readGDelta();
		l+=last;
		modal.polygon_point_list.setPoint(i,l);
		}
	if (addImplecid) {
		modal.polygon_point_list.resize(modal.polygon_point_list.size()+1);
		modal.polygon_point_list.setPoint(modal.polygon_point_list.size()-1,modal.polygon_point_list.point(0));
	}}
	break;
}
 /*if (layout::debug) {
 	for (i=0;i<modal.polygon_point_list.size();i++){
	printf("%d %d\n",modal.polygon_point_list.point(i).x(),modal.polygon_point_list.point(i).y());
	};}*/
 //printf("end pointlist \n");
}

void oasis::readExtension(){
int i=readUnsignedInteger();
if (layout::debug) printf("path extention type %d\n",i);
if ((i&12)==12) {
	modal.path_start_extension_value=readSignedInteger();
	modal.path_start_extension=4;
	if (layout::debug)	printf("start type 4 extension %d\n",modal.path_start_extension_value);}
if ((i&12)==4) modal.path_start_extension=0;
if ((i&12)==8) modal.path_start_extension=2;
if ((i&3)==3) {
	modal.path_end_extension_value=readSignedInteger();
	modal.path_end_extension=4;
	if (layout::debug)	printf("end type 4 extension %d\n",modal.path_start_extension_value);
	}
if ((i&3)==1) {modal.path_end_extension=0;}
if ((i&3)==2) {modal.path_end_extension=2;}
}

QPoint oasis::readGDelta(){
  qint64 i=readUnsignedIntegerLong();
  qint64 k;
  switch (i%2){
  case 0: //form 0
  	i=i>>1;
	k=i%8;
	i=i>>3;
	switch (k){
	case 0: return QPoint(i,0);
		break;
	case 1: return QPoint(0,i);
		break;
	case 2: return QPoint(-i,0);
		break;
	case 3: return QPoint(0,-i);
		break;
	case 4: return QPoint(i,i);
		break;
	case 5: return QPoint(-i,i);
		break;
	case 6: return QPoint(-i,-i);
		break;
	case 7: return QPoint(i,-i);
		break;
	}
  	break;
  case 1: //form 1
  	i=i>>1;
	if (i%2==0) i=i>>1;
	else i=-(i>>1);
	k=readUnsignedInteger();
	if (k%2==0) k=k>>1;
	else k=-(k>>1);
	return QPoint(i,k);
  	break;
  }
 return QPoint(0,0);
}

QPoint oasis::read1Delta(bool dir){
  // dir true-> vertical
  qint64 i=readUnsignedIntegerLong();
  //printf("read1delta %d\n",i);
  switch (i%2){
  case 0:
  	i=(i>>1);
  	break;
  case 1:
  	i=-(i>>1);
  	break;
  }
  if (dir) return QPoint(0,i);
  else  return QPoint(i,0);
}

QPoint oasis::read2Delta(){
  qint64 i=readUnsignedIntegerLong();
  switch (i%4){
  case 0:
  	i=(i>>2);
	return QPoint(i,0);
  	break;
  case 1:
  	i=(i>>2);
	return QPoint(0,i);
  	break;
  case 2:
  	i=-(i>>2);
	return QPoint(i,0);
  	break;
  case 3:
  	i=-(i>>2);
	return QPoint(0,i);
  	break;
  }
  return QPoint(0,0);
}

QPoint oasis::read3Delta(){
  qint64 i=readUnsignedIntegerLong();
  //printf("%d %d\n",i,(i%8));
  switch (i%8){
  case 0:
  	i=(i>>3);
	return QPoint(i,0);
  	break;
  case 1:
  	i=(i>>3);
	return QPoint(0,i);
  	break;
  case 2:
  	i=(i>>3);
	return QPoint(-i,0);
  	break;
  case 3:
  	i=(i>>3);
	return QPoint(0,-i);
  	break;
  case 4:
  	i=(i>>3);
	return QPoint(i,i);
  	break;
  case 5:
  	i=(i>>3);
	return QPoint(-i,i);
  	break;
  case 6:
  	i=(i>>3);
	return QPoint(-i,-i);
  	break;
  case 7:
  	i=(i>>3);
	return QPoint(i,-i);
  	break;
  }
  return QPoint(0,0);
}

QString oasis::readString(){
 uint items=readUnsignedInteger();
  QString s,s1;
  quint8 help;
  uint i;
  s1="";
  for (i=0;i<items;i++){
  	help=readRaw(); 
	if (help!=0){
		s=help; 
		s1+=s;}
	}
  if (layout::debug) printf("string %s\n",s1.toAscii().constData());
  return s1;
}

uint oasis::readUnsignedInteger(){
  quint8 help;
 // uint result=0;
  quint64 result=0;
  int pos=0;
  do {
  	 help=readRaw(); 
	 quint64 h=help&127;
	 result+=(h<<pos);
	 pos+=7;
	 }
  while (help>=128);
  if (pos>35) if (result!=0){
	if (layout::debug) printf("uint with %d bit (%u)/(%llu)\n",pos,(uint)result,result);
	error->addItem(tr("Unsigned Integer with more then 32 Bit."),2);
	//throw QString(tr("Integer with more then 32 Bit."));
	}
 // if (layout::debug) printf("uint %d\n",result);
  return result;
}

quint64 oasis::readUnsignedIntegerLong(){
  quint8 help;
 // uint result=0;
  quint64 result=0;
  int pos=0;
  do {
  	 help=readRaw(); 
	 quint64 h=help&127;
	 result+=(h<<pos);
	 pos+=7;
	 }
  while (help>=128);
  if (pos>60) if (result!=0){
	if (layout::debug) printf("uint with %d bit (%u)/(%llu)\n",pos,(uint)result,result);
	error->addItem(tr("Unsigned Long Integer with more then 60 Bit."),2);
	//throw QString(tr("Integer with more then 32 Bit."));
	}
 // if (layout::debug) printf("uint %d\n",result);
  return result;
}

int oasis::readSignedInteger(){
  quint8 help;
  //int result;
  qint64 result;
  int pos=0;
  help=readRaw(); 
  bool sig=false;
  quint8 h=help&127;
  if ((h%2)==1) sig=true;
  result=(h>>1);
  pos+=6;
  while (help>=128) {
  	 help=readRaw(); 
	 h=help&127;
	 result+=(h<<pos);
	 pos+=7;
	 }
  if (pos>34) if (result!=0)   {
	if (layout::debug) printf("int with %d bit (%d)/%lld\n",pos,(int)result,result);
	error->addItem(tr("Integer with more then 32 Bit."),2);
	//throw QString(tr("Integer with more then 32 Bit."));
	}
  //if (layout::debug){ if (sig) printf("int %d\n",-result); else printf("int %d\n",result);}
  if (sig) return -result;
  else return result;
}

double oasis::readReal(){
 int i=readUnsignedInteger();
 switch (i){
 case 0: return (double)readUnsignedInteger();
 	break;
 case 1: return -(double)readUnsignedInteger();
 	break;
 case 2: return (double)1.0/readUnsignedInteger();
 	break;
 case 3: return -(double)1.0/readUnsignedInteger();
 	break;
 case 4: return (double)readUnsignedInteger()/readUnsignedInteger();
 	break;
 case 5: return -(double)readUnsignedInteger()/readUnsignedInteger();
 	break;
 case 6: { 
 	union {
		float d;
		quint8 a[4];};
	for (uint z=0;z<4;z++){a[z]=readRaw();}
	 return (double) d;}
 	break;
 case 7: { 
 	union {
		double d;
		quint8 a[8];};
	for (uint z=0;z<8;z++){a[z]=readRaw();}
	 return d;}
 	break;
 default:
 	throw QString(tr("Unkown real Format."));
 }
 return 0;
} 

void oasis::readProperty(){
propertyItem p=modal.last_propertiy_name;
 switch (readUnsignedInteger()){
 
 case 0: 
	 p.setValue((int)(readUnsignedInteger()));
 	break;
 case 1:   p.setValue(-(int)(readUnsignedInteger()));
 	break;
 case 2:  p.setValue((float)(1.0)/readUnsignedInteger());
 	break;
 case 3:  p.setValue((float)(-1.0)/readUnsignedInteger());
 	break;
 case 4: p.setValue((float)(1.0)*readUnsignedInteger()/readUnsignedInteger());
 	break;
 case 5: p.setValue((float)(-1.0)*readUnsignedInteger()/readUnsignedInteger());
 	break;
case 6: { 
 	union {
		float d;
		quint8 a[4];};
	for (uint z=0;z<4;z++){a[z]=readRaw();}
	p.setValue(d);
	}
 	break;
 case 7: { 
 	union {
		double d;
		quint8 a[8];};
	for (uint z=0;z<8;z++){a[z]=readRaw();}
	 p.setValue((float)d);
		 }
 	break;
 case 8: p.setValue((int)(readUnsignedInteger()));
 	break;
 case 9: p.setValue((int)(readSignedInteger())); 
 	break;
 case 13:
 case 14:
 case 15: {
	int num=readUnsignedInteger();
	if (num>=(int)(propertyStrings.size())) { QString s;
	   p.setValue(NONEXISTINGPROP+s.setNum(num));}
	else if (propertyStrings[num]=="")p.setValue(num);
	    else p.setValue(propertyStrings[num]);
	  }
 	break;
 default:
 	p.setValue(readString());
 }
 modal.last_property_value_list<<p;
} 
void oasis::zlibInit(uint before, uint after){
 zlib.next_in= &zlibIn[0];
 zlib.next_out= &zlibOut[0];
 zlib.avail_in=zlibBufferSize;
 zlib.avail_out=zlibBufferSize;
 zlib.zalloc=Z_NULL;
 zlib.zfree=Z_NULL;
 zlib.opaque=Z_NULL;
 zlibUsed=true;
 zlibBefore=before;
 zlibAfter=after;
 zlibInPos=0;
 zlibOutPos=0;
 zlibSend();
 //int i=
 inflateInit2(&zlib,-15);
 //int k=
 inflate(&zlib,Z_SYNC_FLUSH); 
 if(zlib.avail_out==zlibBufferSize){
			error->addItem(tr("Error in decompression, no data"),2);
			printf("compression no data: %d %d \n",before,after);
		}
 if (after==0) zlibUsed=false;
}

void oasis::zlibSend(){
uint size=zlibBefore-zlibInPos;
if (size>zlibBufferSize) size=zlibBufferSize;
for (uint i=0;i<size;i++){
  	//(*streamPtr)>>zlibIn[i];
	zlibIn[i]=fread->readUInt8();
	/*QString s;
	s.setNum(zlibIn[i],16);
	if (i==0) printf("zlib send: %s \n",s.toAscii().data());*/
	}
zlibInPos+=size;
zlib.avail_in=size;
zlib.next_in= &zlibIn[0];
//printf("zlib dekompress send in: %d \n",size);
}

quint8 oasis::zlibReadRaw(){
quint8 get=zlibOut[zlibOutPos];
zlibOutPos++;
if (zlibOutPos>=zlibBufferSize-zlib.avail_out) {
	zlib.next_out= &zlibOut[0];
	zlib.avail_out=zlibBufferSize;
	zlibOutPos=0;
	if (zlib.avail_in==0){zlibSend();}
	inflate(&zlib,Z_SYNC_FLUSH); 
	//printf("zlib dekompress: %d \n",zlib.avail_out);
	if(zlib.avail_out==zlibBufferSize){
		if ((zlib.total_out!=zlibAfter)||(zlib.total_in!=zlibBefore))
			error->addItem(tr("Error in decompression"),2);
		inflateEnd(&zlib);
 		zlibUsed=false;
		}
	}
//printf("raw zlib: %d (pos %d of %d)\n",(uint)(get),zlibOutPos,zlib.avail_out);
return get;
}

void oasis::writeSetSimulate(){
zlibBefore=0;
zlibAfter=0;
zlibUsed=true;
zlibSimulate=true;
zlib.next_in= (quint8 *)&zlibIn[0];
zlib.next_out= (quint8 *)&zlibOut[0];
zlib.avail_in=0;
zlib.avail_out=zlibBufferSize;
zlib.zalloc=Z_NULL;
zlib.zfree=Z_NULL;
zlib.opaque=Z_NULL;
zlibInPos=0;
zlibOutPos=0;
deflateInit2(&zlib,Z_DEFAULT_COMPRESSION,Z_DEFLATED,-15,8,Z_DEFAULT_STRATEGY);

}

void oasis::writeSetCompressed(){
zlibBefore=0;
zlibAfter=0;
zlibUsed=true;
zlibSimulate=false;
zlib.next_in= (quint8 *)&zlibIn[0];
zlib.next_out= (quint8 *)&zlibOut[0];
zlib.avail_in=0;
zlib.avail_out=zlibBufferSize;
zlib.zalloc=Z_NULL;
zlib.zfree=Z_NULL;
zlib.opaque=Z_NULL;
zlibInPos=0;
zlibOutPos=0;
deflateInit2(&zlib,Z_DEFAULT_COMPRESSION,Z_DEFLATED,-15,8,Z_DEFAULT_STRATEGY);

}

void oasis::writeEndCompressed(){
int r=-111;
  do{
	r=deflate(&zlib,Z_FINISH);
	if (!zlibSimulate){
		for (uint i=0;i<zlibBufferSize-zlib.avail_out;i++){
			write->writeUInt8(zlibOut[i]);
			}
		//printf("wrote compressed %d\n",zlibBufferSize-zlib.avail_out);
	}
	zlibAfter+=zlibBufferSize-zlib.avail_out;
	zlib.next_out= (quint8 *)&zlibOut[0];
	zlib.avail_out=zlibBufferSize;
	} while (r==Z_FINISH);
  deflateEnd(&zlib);

if (zlibSimulate){
	zlibBeforeSimulated=zlibBefore;
	zlibAfterSimulated=zlibAfter;
	}
else {
	if ((zlibBeforeSimulated!=zlibBefore)||(zlibAfterSimulated!=zlibAfter)){
		if (layout::debug) printf("compression error %d/%d   %d/%d\n",zlibBeforeSimulated,zlibBefore,zlibAfterSimulated,zlibAfter);
		error->addItem(tr("Error with compression, please turn off 'cblock'."),1);
		}
}
zlibUsed=false;
zlibSimulate=false;

}

quint8 oasis::readRaw(){
  if (zlibUsed) return zlibReadRaw();
  //quint8 c;
  //(*streamPtr)>>c;
  //printf("raw: %d\n",(uint)(c));
  return fread->readUInt8();
}

void oasis::setModalAbsoluteMode(){
modal.absoluteMode=true;
writeUnsignedInteger((uint)15);
}

void oasis::resetModal(){

modal.placement_x=0;
modal.placement_y=0;
modal.geometry_x=0;
modal.geometry_y=0;
modal.text_x=0;
modal.text_y=0;
modal.absoluteMode=true;
// undefined
modal.layer=-1;
modal.datatype=-1;
modal.text_string="";
modal.textlayer=-1;
modal.texttype=-1;
modal.circle_radius=-1;
modal.repetition=-1;
modal.ctrapezoid_type=-1;
modal.geometry_w=-1;
modal.geometry_h=-1;
modal.path_halfwidth=-1;
modal.path_start_extension=-1;
modal.path_end_extension=-1;
elementListe.clear();
modal.last_property_value_list.clear();
/* undefined
 placement_cell
   //   int xy_mode;
      QPointArray polygon_point_list;
      QPointArray path_point_list;*/
}

int oasis::readLayer(){
 int i=readUnsignedInteger();
 if (i<0) i=0;
 if (i>=layersMax) i=layersMax-1;
 return i;
}

void oasis::readRepetition(){
int i=readUnsignedInteger();
if (layout::debug) printf("repetition %d\n",i);
switch (i){
  case 0: break;
  case 1: modal.x_dimension=readUnsignedInteger()+2;
  	  modal.y_dimension=readUnsignedInteger()+2;
	  modal.x_space=readUnsignedInteger();
	  modal.y_space=readUnsignedInteger();
	  break;
  case 2: modal.x_dimension=readUnsignedInteger()+2;
	  modal.x_space=readUnsignedInteger();
	  break;
  case 3: 
  	  modal.y_dimension=readUnsignedInteger()+2;
	  modal.y_space=readUnsignedInteger();
	  break;
  case 4: {
	  int k=readUnsignedInteger()+2;
	  int j=0;
	  modal.repArray.resize(k);
	  modal.repArray.setPoint(0,0,0);
	  for (int z=1;z<k;z++){
	  	j+=readUnsignedInteger();
		modal.repArray.setPoint(z,j,0);
		}
	  }
  	  break;
  case 5: {
	  int k=readUnsignedInteger()+2;
	  int j=0;
	  int grid=readUnsignedInteger();
	  modal.repArray.resize(k);
	  modal.repArray.setPoint(0,0,0);
	  for (int z=1;z<k;z++){
	  	j+=(readUnsignedInteger()*grid);
		modal.repArray.setPoint(z,j,0);
		}
	  }
  	  break;
  case 6: {
	  int k=readUnsignedInteger()+2;
	  int j=0;
	  modal.repArray.resize(k);
	  modal.repArray.setPoint(0,0,0);
	  for (int z=1;z<k;z++){
	  	j+=readUnsignedInteger();
		modal.repArray.setPoint(z,0,j);
		}
	  }
  	  break;
  case 7: {
	  int k=readUnsignedInteger()+2;
	  int j=0;
	  int grid=readUnsignedInteger();
	  modal.repArray.resize(k);
	  modal.repArray.setPoint(0,0,0);
	  for (int z=1;z<k;z++){
	  	j+=(readUnsignedInteger()*grid);
		modal.repArray.setPoint(z,0,j);
		}
	  }
  	  break;
  case 8: {
  	  int anz1=readUnsignedInteger()+2;
	  int anz2=readUnsignedInteger()+2;
	  QPoint p1=readGDelta();
	  QPoint p2=readGDelta();
	  modal.repArray.resize(anz1*anz2);
	  for (int x1=0;x1<anz1;x1++){
	  	for (int x2=0;x2<anz2;x2++){
			modal.repArray.setPoint(x1+x2*anz1,x1*p1+x2*p2);	
		}
	  }
  	  }
  	  break;
  case 9: {
  	  int anz1=readUnsignedInteger()+2;
	  QPoint p1=readGDelta();
	  modal.repArray.resize(anz1);
	  for (int x1=0;x1<anz1;x1++){
			modal.repArray.setPoint(x1,x1*p1);	
	  }
  	  }
  	  break;
  case 10:{
	  int k=readUnsignedInteger()+2;
	  QPoint j=QPoint(0,0);
	  modal.repArray.resize(k);
	  modal.repArray.setPoint(0,0,0);
	  for (int z=1;z<k;z++){
	  	j+=(readGDelta());
		modal.repArray.setPoint(z,j);
		}
	  }
  	  break;
  case 11:{
	  int k=readUnsignedInteger()+2;
	  QPoint j=QPoint(0,0);
	  int grid=readUnsignedInteger();
	  modal.repArray.resize(k);
	  modal.repArray.setPoint(0,0,0);
	  for (int z=1;z<k;z++){
	  	j+=(readGDelta()*grid);
		modal.repArray.setPoint(z,j);
		}
	  }
  	  break;
default: throw QString(tr("Repetition unknown."));
}
if (i!=0) modal.repetition=i;
}
void oasis::processRepetition(elementType e){
  if ((modal.repetition<=3)&&(e==cellrefElement)) {
  	switch (modal.repetition){
	case 1: {
		element *element_;
 		element_=cell_->addCellrefArray(modal.placementCell,QPoint(modal.placement_x,modal.placement_y),
				QPoint(modal.x_space,modal.y_space)+QPoint(modal.placement_x,modal.placement_y),modal.x_dimension,modal.y_dimension);
 		element_->setName(modal.placement_cell);
 		element_->rotate(modal.angle);
 		element_->scale(modal.mag);
 		if(modal.mirror_x)element_->setMirrorx();
 		if (layout::debug) printf("insert cellrefarray x:%d ,y:%d\n",modal.placement_x,modal.placement_y);}	
		break;
	case 2: {
		element *element_;
 		element_=cell_->addCellrefArray(modal.placementCell,QPoint(modal.placement_x,modal.placement_y),
				QPoint(modal.x_space,0)+QPoint(modal.placement_x,modal.placement_y),modal.x_dimension,1);
 		element_->setName(modal.placement_cell);
 		element_->rotate(modal.angle);
 		element_->scale(modal.mag);
 		if(modal.mirror_x)element_->setMirrorx();
 		if (layout::debug) printf("insert cellrefarray x:%d ,y:%d\n",modal.placement_x,modal.placement_y);}	
		break;
	case 3: {
		element *element_;
 		element_=cell_->addCellrefArray(modal.placementCell,QPoint(modal.placement_x,modal.placement_y),
				QPoint(0,modal.y_space)+QPoint(modal.placement_x,modal.placement_y),1,modal.y_dimension);
 		element_->setName(modal.placement_cell);
 		element_->rotate(modal.angle);
 		element_->scale(modal.mag);
 		if(modal.mirror_x)element_->setMirrorx();
 		if (layout::debug) printf("insert cellrefarray x:%d ,y:%d\n",modal.placement_x,modal.placement_y);}	
		break;
	}
	}
 else {
  switch (modal.repetition){
  case 1:
  	for (uint x=0;x<modal.x_dimension;x++)
		for (uint y=0;y<modal.y_dimension;y++){
		addElement(e,QPoint(x*modal.x_space,y*modal.y_space));
		}
  	break;
  case 2:
  	for (uint x=0;x<modal.x_dimension;x++){
		addElement(e,QPoint(x*modal.x_space,0));
		}
  	break;
  case 3:
	for (uint y=0;y<modal.y_dimension;y++){
		addElement(e,QPoint(0,y*modal.y_space));
		}
  	break;
  default:
  	for (int x=0;x<modal.repArray.size();x++){
		addElement(e,modal.repArray.point(x));
		}
  	break;
  }
  }
}


void oasis::addElement(elementType e,QPoint p){
 int x;
 int y;
 switch (e){
 	 case boxElement:
	 	x=modal.geometry_x;
 		y=modal.geometry_y;
 		modal.geometry_x+=p.x();
 		modal.geometry_y+=p.y();
		addBox();
		modal.geometry_x=x;
 		modal.geometry_y=y;
		break;
	 case polygonElement:
	 	x=modal.geometry_x;
 		y=modal.geometry_y;
 		modal.geometry_x+=p.x();
 		modal.geometry_y+=p.y();
	  	addPolygon();
		modal.geometry_x=x;
 		modal.geometry_y=y;
		break;
	 case pathElement:
		x=modal.geometry_x;
 		y=modal.geometry_y;
 		modal.geometry_x+=p.x();
 		modal.geometry_y+=p.y();
	  	addPath();
		modal.geometry_x=x;
 		modal.geometry_y=y;
		break;
	 case cellrefElement:
	 	x=modal.placement_x;
 		y=modal.placement_y;
 		modal.placement_x+=p.x();
 		modal.placement_y+=p.y();
	  	addCellref();
		modal.placement_x=x;
 		modal.placement_y=y;
		break;
	 case textElement:
	 	x=modal.text_x;
 		y=modal.text_y;
 		modal.text_x+=p.x();
 		modal.text_y+=p.y();
	  	addText();
		modal.text_x=x;
 		modal.text_y=y;
		break;
	case circleElement:
		x=modal.text_x;
 		y=modal.text_y;
 		modal.text_x+=p.x();
 		modal.text_y+=p.y();
	  	addCircle();
		modal.text_x=x;
 		modal.text_y=y;
		break;
	case trapezoidElement:
		x=modal.text_x;
 		y=modal.text_y;
 		modal.text_x+=p.x();
 		modal.text_y+=p.y();
	  	addTrapezoid();
		modal.text_x=x;
 		modal.text_y=y;
		break;
	case ctrapezoidElement:
		x=modal.text_x;
 		y=modal.text_y;
 		modal.text_x+=p.x();
 		modal.text_y+=p.y();
	  	addCtrapezoid();
		modal.text_x=x;
 		modal.text_y=y;
		break;
	break;
 } 
} 

void oasis::addBox(){
  element *e=cell_->addBox(modal.geometry_x,modal.geometry_y,modal.geometry_w,modal.geometry_h,getMappedLayer());
  e->setDatatype(modal.datatype);
  elementListe<<e;
  if (layout::debug) printf("insert box x:%d ,y:%d\n",modal.geometry_x,modal.geometry_y);
}
void oasis::addCircle(){
  element *e=cell_->addCircle(getMappedLayer(),QPoint(modal.geometry_x,modal.geometry_y),modal.circle_radius);
  e->setDatatype(modal.datatype);
  elementListe<<e;
  if (layout::debug) printf("insert circle x:%d ,y:%d\n",modal.geometry_x,modal.geometry_y);
}
void oasis::addPolygon(){
 pointArray pa;
 QPoint p=QPoint(modal.geometry_x,modal.geometry_y);
 pa.resize(modal.polygon_point_list.size());
 for (int i=0;i<modal.polygon_point_list.size();i++){
 	pa.setPoint(i,modal.polygon_point_list.point(i)+p);
 }
 element *e=cell_->addPolygon(pa,getMappedLayer());
 e->setDatatype(modal.datatype);
 elementListe<<e;
 if (layout::debug) printf("insert polygon x:%d ,y:%d\n",modal.geometry_x,modal.geometry_y);
}
void oasis::addPath(){
 pointArray pa;
 QPoint p=QPoint(modal.geometry_x,modal.geometry_y);
 pa.resize(modal.path_point_list.size());
 for (int i=0;i<modal.path_point_list.size();i++){
 	pa.setPoint(i,modal.path_point_list.point(i)+p);
 }
 element *e=cell_->addPath(pa,getMappedLayer());
 e->setWidth(2*modal.path_halfwidth);
 e->setDatatype(modal.datatype);
 if ((modal.path_start_extension==2)&&(modal.path_end_extension==2)) e->setCap(2);
 else if ((modal.path_start_extension==0)&&(modal.path_end_extension==0)) e->setCap(0);
 else {
  int start=modal.path_start_extension_value;
  int ende=modal.path_end_extension_value;
  if (modal.path_start_extension==2) start=modal.path_halfwidth;
  if (modal.path_end_extension==2) ende=modal.path_halfwidth;
  if (modal.path_start_extension==0) start=0;
  if (modal.path_end_extension==0) ende=0;
  e->expandCaps(start,ende);
  elementListe<<e;
  if (layout::debug) printf("extend path start:%d ,end:%d\n",start,ende);
 }
 if (layout::debug) printf("insert path x:%d ,y:%d\n",modal.geometry_x,modal.geometry_y);
}
void oasis::addCellref(){
 element *element_;
 element_=cell_->addCellref();
 element_->setPos(QPoint(modal.placement_x,modal.placement_y));
 element_->setCellRef(modal.placementCell);
 if (modal.placementCell==NULL) element_->setName(modal.placement_cell);
 element_->rotate(modal.angle);
 element_->scale(modal.mag);
 if(modal.mirror_x)element_->setMirrorx();
 elementListe<<element_;
 if (layout::debug) printf("insert cellref x:%d ,y:%d\n",modal.placement_x,modal.placement_y);
}
void oasis::addText(){
 element *element_=cell_->addText(modal.textlayer,QPoint(modal.text_x,modal.text_y),modal.text_string);
 element_->setWidth(setup::defaultTextWidth);
 element_->setPresentation(setup::defaultTextPresentation);
 element_->setDatatype(modal.texttype);
 elementListe<<element_;
 if (layout::debug) printf("insert text x:%d ,y:%d\n",modal.text_x,modal.text_y);
}
void oasis::addTrapezoid(){
pointArray pa;
pa.resize(5);
//printf("w %d h %d a %d b %d\n",modal.geometry_w,modal.geometry_h,modal.trapezonid_delta_a,modal.trapezonid_delta_b);
if (modal.trapezonid_orientation) {
	if (modal.trapezonid_delta_a<=0) pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	else pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.trapezonid_delta_a));
	if (modal.trapezonid_delta_a<=0)  pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,-modal.trapezonid_delta_a));
	else pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	if (modal.trapezonid_delta_b<=0) pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	else pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h-modal.trapezonid_delta_b));
	if (modal.trapezonid_delta_b<=0) pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h+modal.trapezonid_delta_b));
	else pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	}
else {  if (modal.trapezonid_delta_a<=0) pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)-QPoint(modal.trapezonid_delta_a,0));
	else {pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));};
	if (modal.trapezonid_delta_b>=0) pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w-modal.trapezonid_delta_b,0));
	else  pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	if (modal.trapezonid_delta_b>=0) pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	else  pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w+modal.trapezonid_delta_b,modal.geometry_h));
	if (modal.trapezonid_delta_a<=0) pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	else pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.trapezonid_delta_a,modal.geometry_h));
	}
pa.setPoint(4,pa.point(0));
 element *e=cell_->addPolygon(pa,getMappedLayer());
 e->setDatatype(modal.datatype);
 elementListe<<e;
 if (layout::debug) printf("insert trapezoid x:%d ,y:%d\n",modal.geometry_x,modal.geometry_y);
}

void oasis::addCtrapezoid(){
pointArray pa;
switch (modal.ctrapezoid_type){
case 0: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w-modal.geometry_h,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 1: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w-modal.geometry_h,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 2: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 3: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,0));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 4: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w-modal.geometry_h,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 5: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,0));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w-modal.geometry_h,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 6: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w-modal.geometry_h,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 7: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,0));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w-modal.geometry_h,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 8: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h-modal.geometry_w));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 9: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h-modal.geometry_w));
	pa.setPoint(4,pa.point(0));
	break;
case 10: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 11: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(4,pa.point(0));
	break;
case 12: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h-modal.geometry_w));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 13: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h-modal.geometry_w));
	pa.setPoint(4,pa.point(0));
	break;
case 14: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h-modal.geometry_w));
	pa.setPoint(4,pa.point(0));
	break;
case 15: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h-modal.geometry_w));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 16: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(3,pa.point(0));
	break;
case 17: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(3,pa.point(0));
	break;
case 18: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(3,pa.point(0));
	break;
case 19: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(3,pa.point(0));
	break;
case 20: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(2*modal.geometry_h,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,modal.geometry_h));
	pa.setPoint(3,pa.point(0));
	break;
case 21: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_h,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(2*modal.geometry_h,modal.geometry_h));
	pa.setPoint(3,pa.point(0));
	break;
case 22: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,2*modal.geometry_w));
	pa.setPoint(3,pa.point(0));
	break;
case 23: pa.resize(4);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,2*modal.geometry_w));
	pa.setPoint(3,pa.point(0));
	break;
case 24: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_h));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_h));
	pa.setPoint(4,pa.point(0));
	break;
case 25: pa.resize(5);
	pa.setPoint(0,QPoint(modal.geometry_x,modal.geometry_y));
	pa.setPoint(1,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,0));
	pa.setPoint(2,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(modal.geometry_w,modal.geometry_w));
	pa.setPoint(3,QPoint(modal.geometry_x,modal.geometry_y)+QPoint(0,modal.geometry_w));
	pa.setPoint(4,pa.point(0));
	break;
}
element *e=cell_->addPolygon(pa,getMappedLayer());
 e->setDatatype(modal.datatype);
   elementListe<<e;
 if (layout::debug) printf("insert ctrapezoid x:%d ,y:%d type:%d\n",modal.geometry_x,modal.geometry_y,modal.ctrapezoid_type);
}

void oasis::setPlacementCell(QString cellname){
 if (modal.placement_cell==cellname) return;
 modal.placement_cell=cellname;
 modal.placementCell=cellMap.value(cellname,NULL);
//drawing_->findCell(cellname);
}

void oasis::writeCtrapezoid(int layerNum, int type, int x, int y, int w, int h,int d){
if (!modal.absoluteMode){setModalAbsoluteMode();}
  qint8 info_byte=0;  //write pointlist;
  if (layerNum!=modal.layer) info_byte+=1;
  if (d!=modal.datatype) info_byte+=2;
  if (x!=modal.geometry_x) info_byte+=16;
  if (y!=modal.geometry_y) info_byte+=8;
  if (type!=modal.ctrapezoid_type) info_byte+=128;
  if ((type!=20)&&(type!=21)) if (w!=modal.geometry_w) info_byte+=64;
  if ((type!=16)&&(type!=17)&&(type!=18)&&(type!=19)&&(type!=22)&&(type!=23)&&(type!=25)) if (h!=modal.geometry_h) info_byte+=32;
  if (layout::debug)	
	printf("save CTrapezoid %d\n",type);
  writeUnsignedInteger((uint)26);
  writeRaw(info_byte);
  if (info_byte&1) {
	modal.layer=layerNum;
	writeUnsignedInteger((uint)modal.layer);
	}
  if (info_byte&2) {
	modal.datatype=d;
	writeUnsignedInteger((uint)d);
	}
  if (info_byte&128) {
	modal.ctrapezoid_type=type;
	writeUnsignedInteger((uint)modal.ctrapezoid_type);
	}
  if (info_byte&64) {
	modal.geometry_w=w;
	writeUnsignedInteger((uint)modal.geometry_w);
	}
  if (info_byte&32) {
	modal.geometry_h=h;
	writeUnsignedInteger((uint)modal.geometry_h);
	}
  if (info_byte&16) {
	modal.geometry_x=x;
	writeSignedInteger(modal.geometry_x);
	}
  if (info_byte&8) {
	modal.geometry_y=y;
	writeSignedInteger(modal.geometry_y);}
  if ((type==16)||(type==17)||(type==18)||(type==19)||(type==25)) modal.geometry_h=modal.geometry_w;
  if ((type==20)||(type==21)) modal.geometry_w=2*modal.geometry_h;
  if ((type==22)||(type==23)) modal.geometry_h=2*modal.geometry_w;
}

void oasis::writeTrapezoid(int layerNum, int type, int x, int y, int w, int h, int da, int db, int d){
if (!modal.absoluteMode){setModalAbsoluteMode();}
  qint8 info_byte=0;  //write pointlist;
  if (layerNum!=modal.layer) info_byte+=1;
  if (d!=modal.datatype) info_byte+=2;
  if (x!=modal.geometry_x) info_byte+=16;
  if (y!=modal.geometry_y) info_byte+=8;
  if (type==1) info_byte+=128;
  if (w!=modal.geometry_w) info_byte+=64;
  if (h!=modal.geometry_h) info_byte+=32;
  if (layout::debug)	
	printf("save Trapezoid %d\n",type);
  if (da==0) writeUnsignedInteger((uint)25);
  else if (db==0) writeUnsignedInteger((uint)24);
  else writeUnsignedInteger((uint)23);
  writeRaw(info_byte);
  if (info_byte&1) {
	modal.layer=layerNum;
	writeUnsignedInteger((uint)modal.layer);
	}
  if (info_byte&2) {
	modal.datatype=d;
	writeUnsignedInteger((uint)d);
	}
  if (info_byte&64) {
	modal.geometry_w=w;
	writeUnsignedInteger((uint)modal.geometry_w);
	}
  if (info_byte&32) {
	modal.geometry_h=h;
	writeUnsignedInteger((uint)modal.geometry_h);
	}
   if (da==0) write1Delta(QPoint(db,0),false);
  else if (db==0) write1Delta(QPoint(da,0),false);
  else {	
	write1Delta(QPoint(da,0),false);
  	write1Delta(QPoint(db,0),false);
	} 
  if (info_byte&16) {
	modal.geometry_x=x;
	writeSignedInteger(modal.geometry_x);
	}
  if (info_byte&8) {
	modal.geometry_y=y;
	writeSignedInteger(modal.geometry_y);}
}

void oasis::count(){
recordCount++;
  if ((recordCount%5000)==0){
		QString sh;
		sh.setNum(recordCount);
		drawing->showMessage(tr("%1 elements stored.").arg(sh));
		}
}
int oasis::getMappedLayer(){
	int leLayer=modal.layer;
	if (setup::oasisMapLayer) leLayer=layers::mapLayer(modal.layer,modal.datatype);
	return leLayer;
}

