/***************************************************************************
 *   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.             *
 ***************************************************************************/
//#undef multithread

#include "source.h"
#include <qfile.h>
#include <qdatetime.h>
//Added by qt3to4:
#include "elements/element.h"
#include "elements/cellrefarray.h"
#include "elements/pointarray.h"
#include "general/drawingfield.h"
#include <math.h>
#include "layout.h"
#include "general/errorreport.h"
#include <qmessagebox.h>
#include "elements/propertylist.h"
#ifndef multithread
#include "file_read.h"
#else
#include "threads/fileread.h"
#include "threads/cleandispatcher.h"
#include "elements/polygon.h"
#endif
#include <QFileInfo>

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


source::~source()
{

}

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

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

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

void source::load(QString fileName,drawingField *d, fileOpenType typ){
  errorreport report;
  QString s;
  if (typ==fileImport) {
  	report.setTitle(tr("Import of SOURCE-File \"")+fileName+"\"");}
  else  if (typ==fileOpen){
	report.setTitle(tr("Open of SOURCE-File \"")+fileName+"\"");}
  else  if (typ==fileUpdate){
	report.setTitle(tr("Update with SOURCE-File \"")+fileName+"\"");}
try { 

#ifdef printtime
  setup::centralTimer.start();
#endif

  cellList *firstcellhelp=d->firstCell;
  double databaseunitshelp=d->databaseunits;
  d->databaseunits=setup::sourceDatabase;
  d->userunits=1;
  source sou;
  sou.needCells.clear();
  sou.drawing=d;
  sou.error=&report;
  sou.recordCount=0;
  if ((typ==fileImport)||(typ==fileUpdate)) {
	d->firstCell=NULL;
  }
  QStringList loadedCells;
  QFileInfo fi(fileName);
  QString path=fi.absolutePath();
  QString cell=fi.baseName ();
  QString extension=fi.suffix ();
  sou.open(fileName,cell);
  loadedCells<<cell;
  bool loaded=true;
  while (loaded){
	loaded=false;
	for (int i=0;i<sou.needCells.size();i++){
		if (!loadedCells.contains(sou.needCells.at(i))){
			sou.open(path+"/"+sou.needCells.at(i)+"."+extension,sou.needCells.at(i));
			loadedCells<<sou.needCells.at(i);
			loaded=true;
			}
		}
	}


#ifdef printtime
  printf("source load: %d ms\n", setup::centralTimer.elapsed());
#endif
  // resolving brocken cellrefs
  for (cellList *f =d->firstCell; f!=NULL;f=f->nextCell) {
  	if (f->thisCell!=NULL){
  		for (elementList *e=f->thisCell->firstElement;e!=NULL;e=e->nextElement){
			if (e->thisElement->isCellref()||e->thisElement->isCellrefArray()) {
				//printf("cellref found\n");
				 if (e->thisElement->depend()==NULL){
					//e->thisElement->setCellRef(cellMap.value(e->thisElement->getName(),NULL));
					e->thisElement->setCellRef(d->findCell(e->thisElement->getName()));
					//printf("cellref set\n");
					}
				 if ((e->thisElement->depend()==NULL)&&(typ==fileImport)){  //refs to before existing cells
						cellList *c=d->firstCell;
						d->firstCell=firstcellhelp;
				 		e->thisElement->setCellRef(d->findCell(e->thisElement->getName()));
						d->firstCell=c;}
				 if (e->thisElement->depend()==NULL){
				 	//add empty cells
					cellList *c;
  					c=d->addCell();
  					c->thisCell->cellName=e->thisElement->getName();
					e->thisElement->setCellRef(c->thisCell);
				 	//f->this_cell->deleteElement(e->this_element);
				 	//e=f->this_cell->first_element;
					report.addItem(tr("Cellref(s) can not be resolved. Empty cell added."),1,e->thisElement->getName());}
			}
			if (e==0) {break;}
			
		}
	f->thisCell->clean();
  	}
  }
  //printf("2: %d ms\n", setup::centralTimer.elapsed());
  //  
  d->currentCell=d->findTopCell();
  //printf("3: %d ms\n", setup::centralTimer.elapsed());
  if (d->currentCell==NULL) d->currentCell=d->firstCell->thisCell;
  if ((typ==fileImport)||(typ==fileUpdate)) {
	if (d->databaseunits!=databaseunitshelp) {
		filegeneral::fitDifferentDatabaseunits(&report,d,databaseunitshelp);
		/*report.addItem(tr("Databaseunits are different.Import is fitted."),3,s.setNum(d->databaseunits,'g',10));
		for (cellList *f =d->firstCell; f!=NULL;f=f->nextCell) {f->thisCell->resize(d->databaseunits/databaseunitshelp);}
		d->databaseunits=databaseunitshelp;*/
			}
		}
  //printf("4: %d ms\n", setup::centralTimer.elapsed());
  if (typ==fileImport) {filegeneral::import(&report,d,firstcellhelp);}
  if (typ==fileUpdate) filegeneral::update(&report,d,firstcellhelp);
  if (layout::debug) {printf("Load complete\n");
	}
  //printf("5: %d ms\n", setup::centralTimer.elapsed());
//setup::centralTimer.start();
 } //end try
 catch (QString s){
  if (d->firstCell==NULL) d->firstCell=new cellList();;
  report.addItem(tr("Aborted. ")+s,0);
  report.addItem(s,1);
 }
  //report.showReport(); 
  s=report.getReport();
  d->showReport(s,report.getLastRang());
}

void source::open(QString fileName,QString cellname){
}

int source::readLayer(fileRead *f){
int layer=f->readUInt8();
layer+=(f->readUInt8()*256);
if (layout::debug) printf("layer %d\n",layer);
if (layer>=layersMax) layer=0;
return layer;

}


void source::writeLayer(int l){
write->writeUInt8(l%256);
write->writeUInt8(l/256);
}

int source::readWord(fileRead *f){
int layer=f->readUInt8();
layer+=(f->readUInt8()*256);
if (layout::debug) printf("word %d\n",layer);
return layer;

}

void source::writePos(int l){
}

int source::readPos(fileRead *f,QList<int> *list){
}

QPoint source::readPoint(fileRead *f,QList<int> *li){
QPoint p;
for (char i=0;i<=1;i++){
	int l=readPos(f,li);
	if (i!=0) p.setX((l));
	else p.setY((l));
	}

return p;
}

void source::save(QString fileName,drawingField *d){
}

QString source::cellname(QString name){
QString s=name.left(6);
s=s.trimmed();
return s;
}

void source::save(cell *c){
}

void source::blockTest(int words){
}

void source::count(int words){
recordCount+=words;
  if ((recordCount%5000)==0){
		QString sh;
		sh.setNum(recordCount);
		drawing->showMessage(tr("%1 elements stored.").arg(sh));
		}
}




QString source::readString (fileRead *f,int items){
}

void source::writeOrientation(strans trans){
}

void source::writeString(QString s,bool cell){
}


