/***************************************************************************
 *   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.             *
 ***************************************************************************/
#define _USE_MATH_DEFINES
#include "cell.h"
#include "elementlist.h"
#include "box.h"
#include "polygon.h"
#include "text.h"
#include "general/drawpixmap.h"
#include "cellref.h"
#include "cellrefarray.h"
#include "path.h"
#include <math.h>
#include "general/setup.h"
#include "strans.h"
#include "fileformats/gds.h"
#include "fileformats/oasis.h"
#include "fileformats/cif.h"
#include "fileformats/csv.h"
#include "fileformats/dxf.h"
#include "fileformats/gerber.h"
#include "pointarray.h"
#include <QTextStream>
#include <QSet>
#include <math.h>
#include "bool/booleanhandler.h"


cell::cell() {

    firstElement=NULL;
    cellName="noname";
    date_modification=date_modification.currentDate();
    date_access=date_access.currentDate();
    time_modification=time_modification.currentTime();
    time_access=time_access.currentTime();
    statusPaintInfo=0;

}

cell::~cell() {
    if (firstElement!=NULL) {
        elementList *e;
	while (firstElement!=NULL){
		e=firstElement;
		firstElement=e->nextElement;
		if (e->thisElement!=NULL) delete e->thisElement;
		delete e;
	
        //for (f=firstElement;f!=NULL;f=f->nextElement) {
        //    if (f->thisElement!=NULL) {
        //        delete f->thisElement;
        //        f->thisElement=NULL;
        //    }
        }
        //clean();
    }

}

void cell::deleteSelect() {
    elementList *f;
    if (firstElement!=NULL) {
        for (f=firstElement;f!=NULL;f=f->nextElement) {
            if (f->thisElement!=NULL) {
                if (f->thisElement->select==true) {
                    delete f->thisElement;
                    f->thisElement=NULL;
                } else {
                    f->thisElement->deleteSelect();
                }
            }
        }
        clean();
    }
	paintInfoClear();
}

void cell::moveSelect(QPoint pos) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            f->thisElement->moveSelect(pos);
    }
	paintInfoClear();
}

void cell::move(QPoint pos) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            f->thisElement->move(pos);
    }
	paintInfoClear();
}

void cell::moveToLayerSelect(int layer) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            f->thisElement->moveToLayerSelect(layer);
    }
}

void cell::mapLayer(layerTranslator *t){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            f->thisElement->mapLayer(t);
    }
}

void cell::copySelect(QPoint pos) {
    elementList *f;
    elementList *a,*b;
    element *c=NULL;
    a=NULL;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            if (f->thisElement->select) {
				c=f->thisElement->copy();
                /*if (f->thisElement->isBox()) {
                    c=new box(f->thisElement->getBox());
                }
                if (f->thisElement->isPolygon()) {
                    c=new polygon((f->thisElement->getPolygon()));
                }
                if (f->thisElement->isCellrefArray()) {
                    c=new cellrefArray(f->thisElement->getCellrefArray());
                }
                if (f->thisElement->isCellref()) {
                    c=new cellref(f->thisElement->getCellref());
                }
		if (f->thisElement->isPath()) {
                    c=new path(f->thisElement->getPath());
                }
		if (f->thisElement->isText()) {
                    c=new txt(f->thisElement->getText());
                }
                if (c==NULL) {
                    c=new element();
                    *c=*f->thisElement;
                }*/
                c->select=true;
                f->thisElement->select=false;
                c->move(pos);
                b=new elementList();
                b->thisElement=c;
                b->nextElement=a;
                c=NULL;
                a=b;
            }
        ;
    }
    if (firstElement!=NULL) {
        for (f=firstElement;f->nextElement!=NULL;f=f->nextElement) {}
        f->nextElement=a;
    }
	paintInfoClear();
}

void cell::paintBoundingRec(layoutImagePainter *e,QRgb color){
      	if (statusPaintInfo==0) paintInfoCalc();
	pointArray pa(5);
	pa.setPoint(0,paintInfoMax.x(),paintInfoMax.y());
	pa.setPoint(1,paintInfoMax.x(),paintInfoMin.y());
	pa.setPoint(2,paintInfoMin.x(),paintInfoMin.y());
	pa.setPoint(3,paintInfoMin.x(),paintInfoMax.y());
	pa.setPoint(4,paintInfoMax.x(),paintInfoMax.y());
	e->drawPolygon(&pa,color);
}

void cell::paint(layoutImagePainter *e,bool mainCell) {

    if (*e->paintAbort) return;
    if (statusPaintInfo==0) paintInfoCalc();
	/*	pointArray pa(5);
		pa.setPoint(0,paintInfoMax.x(),paintInfoMax.y());
		pa.setPoint(1,paintInfoMax.x(),paintInfoMin.y());
		pa.setPoint(2,paintInfoMin.x(),paintInfoMin.y());
		pa.setPoint(3,paintInfoMin.x(),paintInfoMax.y());
		pa.setPoint(4,paintInfoMax.x(),paintInfoMax.y());
		e->drawPolygon(&pa,layers::num[0].pen.color().rgb());*/

    if (!e->visibleBox(paintInfoMax,paintInfoMin))
        if (!e->visibleBox(QPoint(paintInfoMax.x(),paintInfoMin.y()),QPoint(paintInfoMin.x(),paintInfoMax.y())))return;
    elementList *f=firstElement;

#ifdef multithread
    if (mainCell) {
	while (true)
		{
			if (f==NULL) return;	
			int delLimit=paintInfoCellElements/8+1;
			if (delLimit>16768) delLimit=16768;
			for (int ic=0;ic<8;++ic){
				
				e->delegate(f,delLimit);
				//printf("delegate: %d %d %d ms\n",this, delLimit,setup::centralTimer.elapsed());
				/*if (k<delLimit) return;*/
				for (int i=0;i<delLimit;++i){
						f=f->nextElement;
						if (f==NULL) return;	
						}
				if (*e->paintAbort) return;
				}
			
			}
	}
    if ((paintInfoElements>(8196))
	&& (paintInfoCellElements> 16))
	 if (e->multiThreadDraw()) {
	//printf("cell %s %d %d\n",cellName.toAscii().data(),paintInfoCellElements,paintInfoElements);
	// paintInfoCellElements nicht immer aktuell !!!
	int k=paintInfoCellElements;
	while (f!=NULL){
		while (e->LImage->jobs.available()>64){
			//printf("cell %d %d %d %d\n",this,paintInfoCellElements,paintInfoElements,k);
			for (int ic=0;ic<1024;++ic){
				if (f->thisElement!=NULL) {
					f->thisElement->paint(e);
				}
				--k;
				f=f->nextElement;
				if (f==NULL) return;
			}
			if (*e->paintAbort) return;
			}
		if ((k<16)) {
			while (true){
			if (f->thisElement!=NULL) {
					f->thisElement->paint(e);
				}
			f=f->nextElement;
			if (f==NULL) return;
			}
		}
		/*if (k<2048) {
			e->delegate(f,k);
			return;
			}*/
		int delLimit=2048;
		//if (delLimit>4096) delLimit=4096;
		//while (true)
		{
			delLimit=(e->LImage->jobs.available()<<8)+1024;
			if (delLimit>16768) delLimit=16768;
			for (int ic=0;ic<8;++ic){
				
				e->delegate(f,delLimit);
				//printf("delegate: %d %d %d ms\n",this, delLimit,setup::centralTimer.elapsed());
				/*if (k<delLimit) return;*/
				for (int i=0;i<delLimit;++i){
						f=f->nextElement;
						if (f==NULL) return;	
						}
				k-=delLimit;
				if (*e->paintAbort) return;
				}
			
			}
	}
	}
#endif
    for (;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
/*	    if (f->thisElement->isText()) printf("text\n");
	    if (f->thisElement->isBox()) printf("box\n");
	    if (f->thisElement->isPolygon()) printf("polygon\n");
	    if (f->thisElement->isPath()) printf("path\n");
	    if (f->thisElement->isCellref()) printf("cellref\n");
	    if (f->thisElement->isCellrefArray()) printf("cellrefarray\n");*/

	   f->thisElement->paint(e);
        }
    }
}

void cell::paintSelect(layoutImagePainter *e) {
    if (statusPaintInfo==0) paintInfoCalc();
    if (!e->visibleBox(paintInfoMax,paintInfoMin))return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->paintSelect(e);
        }
    }
}

void cell::paintSelected(layoutImagePainter *e) {
    if (statusPaintInfo==0) paintInfoCalc();
    if (!e->visibleBox(paintInfoMax,paintInfoMin))return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->paintSelected(e);
        }
    }
}

void cell::paintNode(int node, layoutImagePainter *e){
    if (statusPaintInfo==0) paintInfoCalc();
    if (!e->visibleBox(paintInfoMax,paintInfoMin))return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->paintNode(node,e);
        }
    }
}

void cell::paintDevice(QString device, layoutImagePainter *e){
    if (statusPaintInfo==0) paintInfoCalc();
    if (!e->visibleBox(paintInfoMax,paintInfoMin))return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->paintDevice(device,e);
        }
    }
}

void cell::paintDeviceNode(QString device,int node, layoutImagePainter *e){
    if (statusPaintInfo==0) paintInfoCalc();
    if (!e->visibleBox(paintInfoMax,paintInfoMin))return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->paintDeviceNode(device,node,e);
        }
    }
}

void cell::paintHighlighted(QPainter *po,strans trans_) {
    if (statusPaintInfo==0) paintInfoCalc();
    if (paintInfoElements>500) {
	   po->setPen(setup::highlightColor);
	   //po->drawRect(QRect(paintInfoMax,paintInfoMin));
	   po->drawPolygon(element::convert(QRect(paintInfoMax,paintInfoMin),trans_));
	return; 
    }
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->paintHighlighted(po,trans_);
        }
    }
}

void cell::paintHighlightedBoundingRec(QPainter *po,strans trans_){
	if (statusPaintInfo==0) paintInfoCalc();

	po->setPen(setup::highlightColor);
	   //po->drawRect(QRect(paintInfoMax,paintInfoMin));
	po->drawPolygon(element::convert(QRect(paintInfoMax,paintInfoMin),trans_));
}

void cell::fSelect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->fSelect(select);
        }
    }
}

void cell::fSelectLayer(QRect select, int layer){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->fSelectLayer(select,layer);
        }
    }
}

void cell::fDeselectLayer(QRect select, int layer){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->fDeselectLayer(select,layer);
        }
    }
}

void cell::fAllSelect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->fAllSelect(select);
        }
    }
}

void cell::pSelect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->pSelect(select);
        }
    }
}

void cell::cSelect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->cSelect(select);
        }
    }
}

void cell::fDeselect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->fDeselect(select);
        }
    }
}

void cell::fAllDeselect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->fAllDeselect(select);
        }
    }
}

void cell::pDeselect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->pDeselect(select);
        }
    }
}

void cell::cDeselect(QRect select) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->cDeselect(select);
        }
    }
}

void cell::sizeadjustSelect(int value) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->sizeadjustSelect(value);
        }
    }
    clean();
    paintInfoClear();
}

void cell::sizeadjustSelect(int valueX, int valueY) {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
		if (f->thisElement->select) {
			if (f->thisElement->isPath()){
				element *p=f->thisElement->convertToPolygon();
				if (p!=NULL) {
					p->select=true;
					delete f->thisElement;
					f->thisElement=p;
					}
				}
           	 f->thisElement->sizeadjustSelect(valueX,valueY);
	}
    }
    clean();
    paintInfoClear();
}

void cell::modifyCornersSelect(double value1, double value2){
    toPolygonSelect();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
		f->thisElement->modifyCornersSelect(value1,value2);
        }
    }
    clean();
    paintInfoClear();
}

void cell::cropWithSelection(){
   elementList *cropElements=NULL;
   elementList *newElements=NULL;
   elementList *f,*j;
   toPolygonSelect();
   QPoint maxCrop=QPoint(INT_MIN,INT_MIN);
   QPoint minCrop=QPoint(INT_MAX,INT_MAX);
   for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            if (f->thisElement->select){
		if (!f->thisElement->isPolygon()){
			element *e=f->thisElement;
			f->thisElement=NULL;
			delete e;
			}
		else {
			f->thisElement->minimum(&minCrop);
   			f->thisElement->maximum(&maxCrop);
			j=cropElements;
			cropElements=new elementList();
			cropElements->thisElement=f->thisElement;
			cropElements->nextElement=j;
			f->thisElement=NULL;
			}
		}
        }
   }
   if (cropElements==NULL) return;
   while (firstElement!=NULL){
   //int count=0;
   for (f=firstElement;f!=NULL;f=f->nextElement) {
   //count++;
        if (f->thisElement!=NULL) {
		if ((f->thisElement->isPolygon())||(f->thisElement->isBox())) {
			booleanHandler boolean;
			pointArray pa=f->thisElement->getPoints();
			if (f->thisElement->isBox()){
				polygon *p=f->thisElement->convertToPolygon();
				pa=p->getPoints();
				delete p;
			}
			boolean.setA(&pa);
			for (j=cropElements;j!=NULL;j=j->nextElement)
				if (j->thisElement!=NULL){
					pointArray pa2=j->thisElement->getPoints();
					boolean.setB(&pa2);
			}
			QList<pointArray> pl=boolean.getAMultiB();
			pointArray pa2;
			pa2.resize(0);
			if (pl.size()==1) {pa2=pl.at(0);pa2.clean();}
			if ((pl.size()==1)&& (pa.identical(pa2))) {
					j=newElements;
					newElements=new elementList();
					newElements->nextElement=j;
					newElements->thisElement=f->thisElement;
					f->thisElement=NULL;
				}
			else {
				for (int k=0;k<pl.size();k++){
					j=newElements;
					newElements=new elementList();
					newElements->nextElement=j;
					newElements->thisElement=new polygon(pl.at(k),f->thisElement->layerNum);
					newElements->thisElement->property=f->thisElement->property;
					newElements->thisElement->datatype=f->thisElement->datatype;
					}
				delete f->thisElement;
				f->thisElement=NULL;
				}
			}
		else if (f->thisElement->isPath()){
				bool use=true;
				bool pointIn=false;
				pointArray pa=f->thisElement->getPoints();
				for (int i=0;i<pa.size();i++){
					pointIn=false;
					for (j=cropElements;j!=NULL;j=j->nextElement)
						if (j->thisElement!=NULL){
							pointArray pa2=j->thisElement->getPoints();
							if (element::pointInPolygon(pa2,pa.point(i))){
								pointIn=true;
							}
					}
					if (!pointIn) use=false;
				}
				if (use) {
					j=newElements;
					newElements=new elementList();
					newElements->nextElement=j;
					newElements->thisElement=f->thisElement;
					f->thisElement=NULL;
				} else
				   if (f->thisElement->getWidth()<=0) f->thisElement->select=true;
			}
		else if (f->thisElement->isText()){
				bool use=false;
				pointArray pa=f->thisElement->getPoints();
				for (j=cropElements;j!=NULL;j=j->nextElement)
					if (j->thisElement!=NULL){
						pointArray pa2=j->thisElement->getPoints();
						if (element::pointInPolygon(pa2,pa.point(0))){
							use=true;
						}
				}
				if (use) {
					j=newElements;
					newElements=new elementList();
					newElements->nextElement=j;
					newElements->thisElement=f->thisElement;
					f->thisElement=NULL;
				} else
				   if (f->thisElement->getWidth()<=0) f->thisElement->select=true;
			}
		else if ((f->thisElement->isCellref())||(f->thisElement->isCellrefArray())){
			   //printf(".");
			booleanHandler boolean;
			QPoint max=QPoint(INT_MIN,INT_MIN);
			QPoint min=QPoint(INT_MAX,INT_MAX);
			f->thisElement->minimum(&min);
			f->thisElement->maximum(&max);
			bool b=false;
			if (max.x()<minCrop.x()) b=true;
			if (max.y()<minCrop.y()) b=true;
			if (min.x()>maxCrop.x()) b=true;
			if (min.y()>maxCrop.y()) b=true;
			if (!b){
				pointArray pa(5);
				pa.setPoint(0,min.x(),min.y());
				pa.setPoint(1,max.x(),min.y());
				pa.setPoint(2,max.x(),max.y());
				pa.setPoint(3,min.x(),max.y());
				pa.setPoint(4,min.x(),min.y());
				boolean.setA(&pa);
				for (j=cropElements;j!=NULL;j=j->nextElement)
					if (j->thisElement!=NULL){
						pointArray pa2=j->thisElement->getPoints();
						boolean.setB(&pa2);
				}
				QList<pointArray> pl=boolean.getAMultiB();
				pointArray pa2;
				pa2.resize(0);
				if (pl.size()==1) {pa2=pl.at(0);pa2.clean();}
				if ((pl.size()==1)&& (pa.identical(pa2))) {
						j=newElements;
						newElements=new elementList();
						newElements->nextElement=j;
						newElements->thisElement=f->thisElement;
						f->thisElement=NULL;
					}
				
			}
			else f->thisElement->select=true;
			}
		else f->thisElement->select=true;
		}
	
   }
   //printf("%d\n",count);
   clean();
   deleteSelect();
   selectAll();
   toPolygonSelect();
   flatSelect();
   deselectAll();
   }

   firstElement=newElements;
   //remove cutting elements
   while (cropElements!=NULL){
	f=cropElements;
	cropElements=cropElements->nextElement;
	delete f->thisElement;
	delete f;
	};
}


element* cell::addBox(QRect r,int layer){

    elementList *e=addElement();
    e->thisElement=new box(r,layer);
    paintInfoClear();
    return e->thisElement;
}


element* cell::addBox(int x,int y, int b, int h,int layer) {
    elementList *e=addElement();
    e->thisElement=new box(x,y,b,h,layer);
    paintInfoClear();
    return e->thisElement;
}

element* cell::addBox(pointArray points,int layer) {
    paintInfoClear();
    elementList *e=addElement();
    if (points.size()!=5) {
        e->thisElement = new polygon(points,layer);
        return e->thisElement;
    }
    if (points.point(0)!=points.point(4)) {
        e->thisElement = new polygon(points,layer);
        return e->thisElement;
    }
    QPoint p;
    int x1,x2,y1,y2;
    p=points.point(0);
    x1=p.x();
    y1=p.y();
    p=points.point(1);
    if (p.x()<x1) {
        x2=x1;
        x1=p.x();
    } else {
        x2=p.x();
    }
    if (p.y()<y1) {
        y2=y1;
        y1=p.y();
    } else {
        y2=p.y();
    }
    for (int i=2;i<4;i++) {
        p=points.point(i);
        if (p.x()<x1) {
            x1=p.x();
        }
        if (p.x()>x2) {
            x2=p.x();
        }
        if (p.y()<y1) {
            y1=p.y();
        }
        if (p.y()>y2) {
            y2=p.y();
        }
    }
    bool b=true;
    for (int i=0;i<4;i++) {
        p=points.point(i);
        if ((p.x()!=x1)&&(p.x()!=x2))
            b=false;
        if ((p.y()!=y1)&&(p.y()!=y2))
            b=false;
    }
    if (b) {
        e->thisElement=new box(x1,y1,(x2-x1),(y2-y1),layer);
        return e->thisElement;
    } else {
        e->thisElement = new polygon(points,layer);
        return e->thisElement;
    }
}

element* cell::addRoundedBox(int x,int y,int b, int h,int r, int layer){
paintInfoClear();
if (r==0) return addBox(x,y,b,h,layer);
if (b<0) {
	b=-b;
	x-=b;
}
if (h<0) {
	h=-h;
	y-=h;
}
if (b<2*r) return NULL;
if (h<2*r) return NULL;
pointArray pa;
pa<<QPoint(x+r,y);
pa<<element::spirale(QPoint(x+b-r,y+r),QPoint(x+b-r,y),QPoint(x+b,y+r),setup::circularDefault);
pa<<element::spirale(QPoint(x+b-r,y+h-r),QPoint(x+b,y+h-r),QPoint(x+b-r,y+h),setup::circularDefault);
pa<<element::spirale(QPoint(x+r,y+h-r),QPoint(x+r,y+h),QPoint(x,y+h-r),setup::circularDefault);
pa<<element::spirale(QPoint(x+r,y+r),QPoint(x,y+r),QPoint(x+r,y),setup::circularDefault);
return addPolygon(pa,layer);
}

element* cell::addEllipse(int layer,QPoint center,int rx,int ry){
paintInfoClear();
int x=center.x();
int y=center.y();
pointArray pa;
pa<<element::ellipse(QPoint(x,y),rx,ry,setup::circularDefault);
return addPolygon(pa,layer);
}


element* cell::addPolygon(pointArray points,int layer) {
    paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new polygon(points,layer);
    return e->thisElement;
}

element* cell::addCircle(int layer,QPoint center,int radius){
    paintInfoClear();
    pointArray points=element::spirale(center,center+QPoint(radius,0),center+QPoint(radius,0),setup::circularDefault);
    elementList *e=addElement();
    e->thisElement = new polygon(points,layer);
    return e->thisElement;
}

element* cell::addPath(pointArray points,int layer) {
    paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new path(points,layer);
    return e->thisElement;
}

element* cell::addCellref(cell *c,QPoint pos) {
   paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new cellref( c, pos);
    return e->thisElement;
}

element* cell::addCellrefArray(cell *c,pointArray array,int anzx,int anzy) {
   paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new cellrefArray( c, array,anzx,anzy);
    return e->thisElement;
}

element* cell::addCellrefArray(cell *c,QPoint pos1,QPoint pos2,int anzx,int anzy) {
    paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new cellrefArray( c,  pos1, pos2,anzx,anzy);
    return e->thisElement;
}

element* cell::addCellrefArray(cell *c,QPoint pos1,QPoint pos2,int anzx,int anzy,strans trans) {
   paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new cellrefArray( c,  pos1, pos2,anzx,anzy,trans);
    return e->thisElement;
}

element* cell::addCellref() {
    paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new cellref();
    return e->thisElement;
}

element* cell::addCellrefArray() {
    paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new cellrefArray();
    return e->thisElement;
}

element* cell::addText(int layer,QPoint pos,QString text) {
    paintInfoClear();
    elementList *e=addElement();
    e->thisElement = new txt(layer,pos,text);
    return e->thisElement;
}

void cell::resize(double size) {
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->resize(size);
        }
    }
}

void cell::resize(double scale,int mod, bool *b){ // data lost ?
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->resize(scale,mod,b);
        }
   }
}

element* cell::addElement(element *e){
   
elementList *el=addElement();
el->thisElement=e;
return e;
}

elementList* cell::addElement() {

    paintInfoClear();
    //statusPaintInfo=0;
    //printf("-1#\n");
    elementList *e;
    if (firstElement!=NULL) {
            e=new elementList();
            e->nextElement=firstElement;
	    firstElement=e;
            return e;
        } else {
            firstElement=new elementList();
            return firstElement;
        }
}

void cell::minimum(QPoint *pos) {
 if (statusPaintInfo==0) paintInfoCalc();
 if ((paintInfoMin.x()>pos->x())&&(paintInfoMin.y()>pos->y()))return;
 if (statusPaintInfo<2) paintInfoMinMax();
 if (paintInfoMin.x()<pos->x()) pos->setX(paintInfoMin.x());
 if (paintInfoMin.y()<pos->y()) pos->setY(paintInfoMin.y());
 /*
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->minimum(pos);
        }
    }*/
}

void cell::maximum(QPoint *pos) {
 if (statusPaintInfo==0) paintInfoCalc();
 if ((paintInfoMax.x()<pos->x())&&(paintInfoMax.y()<pos->y()))return;
 if (statusPaintInfo<2) paintInfoMinMax();
 if (paintInfoMax.x()>pos->x()) pos->setX(paintInfoMax.x());
 if (paintInfoMax.y()>pos->y()) pos->setY(paintInfoMax.y());
   /* elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->maximum(pos);
        }
    }*/
}

void cell::minimumSelect(QPoint *pos) {
    if (statusPaintInfo==0) paintInfoCalc();
    if ((paintInfoMin.x()>pos->x())&&(paintInfoMin.y()>pos->y()))return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->minimumSelect(pos);
        }
    }
}

void cell::maximumSelect(QPoint *pos) {
    if (statusPaintInfo==0) paintInfoCalc();
    if ((paintInfoMax.x()<pos->x())&&(paintInfoMax.y()<pos->y()))return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->maximumSelect(pos);
        }
    }
}
/*
int cell::minSize() {
    elementList *f;
    int size=1<<30;
    int i;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            i=f->thisElement->minSize();
	    if ((i>0)&&(i<size)) size=i;
        }
    }
    return size;
}

int cell::minSizeSelect() {
    elementList *f;
    int size=1<<30;
    int i;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            i=f->thisElement->minSizeSelect();
	    if ((i>0)&&(i<size)) size=i;
        }
    }
    return size;
}*/

void cell::updateCellref(cell* oldCell, cell* newCell){
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            if (f->thisElement->depend()==oldCell)f->thisElement->setCellRef(newCell);
        }
    }
}

void cell::deleteElement(element *c) {
    paintInfoClear();
    elementList *f;
    if (firstElement!=NULL) {
        for (f=firstElement;f!=NULL;f=f->nextElement) {
            if (f->thisElement!=NULL) {
                if (f->thisElement==c) {
                    delete f->thisElement;
                    f->thisElement=NULL;
                }
            }
        }
        clean();
    }
}

void cell::deleteRefs(cell* cell) {
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            if (f->thisElement->depend()==cell) {
                delete f->thisElement;
                f->thisElement=NULL;
            }
    }
    clean();
}

void cell::clean() {
    elementList *f,*help;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            if (!f->thisElement->correct()) {
                delete f->thisElement;
                f->thisElement=NULL;
            }
    }
    // NULL elemente entfernen
    if (firstElement!=NULL) {
        help=firstElement;
        if (firstElement->nextElement!=NULL) {
            for (f=firstElement->nextElement;f!=NULL;) {
                if (f->thisElement==NULL) {
                    help->nextElement=f->nextElement;
                    delete f;
                    f=help->nextElement;
                } else {
                    help=f;
                    f=f->nextElement;
                }
            }
        }
        if (firstElement->thisElement==NULL) {
            help=firstElement;
            firstElement=firstElement->nextElement;
            delete help;
        }
    }
}

bool cell::depend(cell* cell) {
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp==cell) {
                return true;
            } else {
                if ((cellhelp!=NULL)) {
                    if (cellhelp->depend(cell)) return true;
                }
            }
        }
    }
 return false;
}

QStringList cell::usedCells(){
  QSet<cell*> cells;
  QStringList list;
  class cell  *cellhelp;
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
	    if (cellhelp!=NULL){
	      if (!cells.contains(cellhelp)){
		cells<<cellhelp;
		list<<cellhelp->cellName;
	      }
	    }
        }
    }
  return list;
}




bool cell::useCell(cell* cell) {
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp==cell) {
                return true;
            } 
        }
    }
    return false;
}

void cell::compare(cell*cell){
bool b=true;
    elementList *f1,*f2;
    selectAll();
    cell->selectAll();
    for (f1=firstElement;f1!=NULL;f1=f1->nextElement) {
	b=true;
        if (f1->thisElement!=NULL) if (f1->thisElement->select) {
		for (f2=cell->firstElement;f2!=NULL;f2=f2->nextElement) 
       			if (b) if (f2->thisElement!=NULL) if (f2->thisElement->select)
				if (f2->thisElement->identical(f1->thisElement)) {
						f2->thisElement->select=false;
						f1->thisElement->select=false;
						b=false;
						}
            	}
    }
}

bool cell::identical(cell* cell) {
    bool b=true;
    elementList *f1,*f2;
    selectAll();
    cell->selectAll();
    for (f1=firstElement;f1!=NULL;f1=f1->nextElement) {
	b=true;
        if (f1->thisElement!=NULL) if (f1->thisElement->select) {
		for (f2=cell->firstElement;f2!=NULL;f2=f2->nextElement) 
       			if (b) if (f2->thisElement!=NULL) if (f2->thisElement->select)
				if (f2->thisElement->identical(f1->thisElement)) {
						f2->thisElement->select=false;
						f1->thisElement->select=false;
						b=false;
						}
            	}
	if (b) { 
		cell->deselectAll();
		deselectAll();
		return false;
		}
    }

    elementCount ec1=countSelect();
    elementCount ec2=cell->countSelect();
    int i=0;
    i=ec1.box+ec1.cellref+ec1.cellrefarray+ec1.path+ec1.polygon+ec1.text;
    i+=ec2.box+ec2.cellref+ec2.cellrefarray+ec2.path+ec2.polygon+ec2.text;
	cell->deselectAll();
	deselectAll();
    if (i==0) return true;
    return false;
}


void cell::relink(cell* cellold,cell* cellnew) {
    if ((cellold==NULL)||(cellnew==NULL)) return;
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp==cellold) {
                f->thisElement->setCellRef(cellnew);
            } 
        }
    }
}

void cell::relinkSelect(cell*Cellnew){
    if ((Cellnew==NULL)) return;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    if (f->thisElement->select)
		f->thisElement->setCellRef(Cellnew);
    }
}

void cell::removeDepend(QHash<cell*,bool> *l){
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp!=NULL) {
			(*l)[cellhelp]=false;
                }
            }
        }
}
void cell::removeDependMultilevel(QHash<cell*,bool> *l){
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if ((cellhelp!=NULL)) {
			if ((*l)[cellhelp])
			    cellhelp->removeDependMultilevel(l);
			(*l)[cellhelp]=false;
                }
            }
        }
}

void cell::removeDependSelectMultilevel(QHash<cell*,bool> *l){
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if ((cellhelp!=NULL)&&(f->thisElement->select)) {
			if ((*l)[cellhelp])
			    cellhelp->removeDependMultilevel(l);
			(*l)[cellhelp]=false;
                }
            }
        }
}

/*
//unbenutzt
void cell::unmarkDepend(cellList *first_cell){
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp!=NULL) {
			cellList *cell_list;
 			 for (cell_list=first_cell;cell_list!=NULL;cell_list=cell_list->next_cell){
    			   if (cellhelp==cell_list->thisCell) cell_list->thisCell->marker=false;
  			}
                }
            }
        }
}
*/

void cell::markDepend(){
    class cell  *cellhelp;
    elementList *f;
    marker=true;
    //printf("%s\n",cellName.toAscii().data());
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp!=NULL) {
			if (cellhelp->marker==false) cellhelp->markDepend();
                }
        }
    }
}

int cell::countDepend(){
    if (markerInt.size()==1) return markerInt.at(0);
    markerInt.clear();
    int count=0;
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp!=NULL) {
			count+=cellhelp->countDepend()+1;
  			}
                }
        }
    //printf("%d %s <--\n",count,cellName.toAscii().data());
    markerInt<<count;
    return count;
}

void cell::listDepend(){
    markerList.clear();
    markerInt.clear();
    QHash<QString,int> cellMap;
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp!=NULL) {
			cellMap[cellhelp->cellName]=cellMap.value(cellhelp->cellName,0)+1;
			/*cellList *cell_list;
 			 for (cell_list=first_cell;cell_list!=NULL;cell_list=cell_list->next_cell){
    			   if (cellhelp==cell_list->thisCell)  
					   if (!markerList.contains(cell_list->thisCell->cellName)) {
						   markerList.append(cell_list->thisCell->cellName);
						   markerInt.append(1);
					   }
					   else {
						   int k=markerList.indexOf(cell_list->thisCell->cellName);
						   markerInt[k]++;
					   }
  			}*/
                }
            }
        }
	markerList=cellMap.keys();
	markerList.sort();
	int size=markerList.size();
	for (int i=0;i<size;i++){
		markerInt<<cellMap.value(markerList.at(i),0);
	}
	//printf("%s -> %d\n",cellName.toAscii().data(),size);
	/*QMap<QString, int> map; 
	for (int i=0;i<markerList.size();i++){
		map[markerList[i]]=markerInt[i];
	}
    markerList.sort();
   	for (int i=0;i<markerList.size();i++){
		markerInt[i]=map[markerList[i]];
	}*/
}

/*
void cell::listDependMultilevel(cellList *first_cell,QStringList *list){
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp!=NULL) {
			cellList *cell_list;
 			 for (cell_list=first_cell;cell_list!=NULL;cell_list=cell_list->next_cell){
    			   if (cellhelp==cell_list->thisCell)  
				if (!list->contains(cell_list->thisCell->cellName)) { 	
					list->append(cell_list->thisCell->cellName);
			   		cell_list->thisCell->listDependMultilevel(first_cell,list);
			    }
  			}
                }
            }
        }
}

void cell::listDependMultilevelSelect(cellList *first_cell,QStringList *list){
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if ((cellhelp!=NULL)&&(f->thisElement->select)) {
			//cellList *cell_list=cellhelp;
 			 //for (cell_list=first_cell;cell_list!=NULL;cell_list=cell_list->next_cell){
    			   //if (cellhelp==cell_list->thisCell)  
				if (!list->contains(cellhelp->cellName)) { 	
					list->append(cellhelp->cellName);
			   		cellhelp->listDependMultilevel(first_cell,list);
			    //}
  			}
                }
            }
        }
}
*/

bool cell::dependNotSaved() {
    bool b=false;
    class cell  *cellhelp;
    elementList *f;
    if (saved) {
        return false;
    }
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if ((cellhelp!=NULL)&&(!b)) {
                if (!cellhelp->saved) {
                    b=true;
                }
            }
        }
    }
    return b;
}

void cell::saveGDS(gds *g){
    //bgnstr
    g->write->writeUInt16(28);
    g->write->writeUInt8(5);
    g->write->writeUInt8(2);
    g->write->writeInt16((qint16)(date_modification.year()-1900));
    g->write->writeInt16((qint16)date_modification.month());
    g->write->writeInt16((qint16)(date_modification.day()));
    g->write->writeInt16((qint16)(time_modification.hour()));
    g->write->writeInt16((qint16)(time_modification.minute()));
    g->write->writeInt16((qint16)(time_modification.second()));
    g->write->writeInt16((qint16)(date_access.year()-1900));
    g->write->writeInt16((qint16)(date_access.month()));
    g->write->writeInt16((qint16)(date_access.day()));
    g->write->writeInt16((qint16)(time_access.hour()));
    g->write->writeInt16((qint16)(time_access.minute()));
    g->write->writeInt16((qint16)(time_access.second()));
    g->writeString(cellName,6);
   /* (*g->streamPtr)<<(quint16) 28<<(quint8) 5<<(quint8)2<< (qint16)(date_modification.year()-1900)<< (qint16)(date_modification.month())<< (qint16)(date_modification.day())<< (qint16)(time_modification.hour())<< (qint16)(time_modification.minute())<< (qint16)(time_modification.second()); //bgnstr
    (*g->streamPtr)<< (qint16)(date_access.year()-1900)<< (qint16)(date_access.month())<< (qint16)(date_access.day())<< (qint16)(time_access.hour())<< (qint16)(time_access.minute())<< (qint16)(time_access.second()); //bgnstr
    g->writeString(cellName,6);*/
    // elemente
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveGDS(g);
        }
    }
    //endstr
    g->write->writeUInt16(4);
    g->write->writeUInt8(7);
    g->write->writeUInt8(0);
    //(*g->streamPtr)<<(quint16) 4<<(quint8) 7<<(quint8)0;  //endstr
    saved=true;
}



void cell::saveDXF(dxf *stream) {
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveDXF(stream);
        }
    }
    saved=true;
}

void cell::saveSVG(svg *s){
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveSVG(s);
        }
    }
    saved=true;
}

void cell::saveSelect(QDataStream *stream){
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveSelect(stream);
        }
    }
}

void cell::save(QDataStream *stream){
   (*stream)<<(qint8)(5);
   (*stream)<<(qint16)cellName.length();
   if (cellName.length()!=0) stream->writeRawData (cellName.toAscii().data(), cellName.length() );
   elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->save(stream);
        }
    }
    (*stream)<<(qint8)(6);
    saved=true;
}
 
void cell::saveOASIS(oasis *o){
 if (!setup::oasisSaveCBlock) {
  o->writeUnsignedInteger((uint)14);
  o->writeString(cellName);
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveOASIS(o);
        }
    }
    saved=true;
 }
 else {
  // use cblock
//printf("oasis use compressed block \n");
  o->writeSetSimulate();
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveOASIS(o);
        }
    }
  o->writeEndCompressed();
  o->resetModal();
  if (o->zlibBeforeSimulated>o->zlibAfterSimulated){
	//save compressed
	o->writeUnsignedInteger((uint)14);
	o->writeString(cellName);
	o->writeUnsignedInteger((uint)34);
	o->writeUnsignedInteger((uint)0);
	o->writeUnsignedInteger(o->zlibBeforeSimulated);
	o->writeUnsignedInteger(o->zlibAfterSimulated);
	o->writeSetCompressed();
	for (f=firstElement;f!=NULL;f=f->nextElement) {
		if (f->thisElement!=NULL) {
		f->thisElement->saveOASIS(o);
		}
	}
	saved=true;
	o->writeEndCompressed();
	}
  else {
	//save uncompressed
	o->writeUnsignedInteger((uint)14);
	o->writeString(cellName);
	//printf("uncompressed %s\n",cellName.toAscii().data());
	elementList *f;
	for (f=firstElement;f!=NULL;f=f->nextElement) {
		if (f->thisElement!=NULL) {
		f->thisElement->saveOASIS(o);
		}
	}
	saved=true;
	}
 }
}
void cell::saveCIF(cif *o){
  
  QString s="DS ";
  QString s1;
  s+=s1.setNum(o->cellNum)+" ";
  s+=s1.setNum(o->a)+" ";
  s+=s1.setNum(o->b);
  o->writeEntry(s);
  s=cellName;
  s=s.replace( ' ', "_");
  s="9 "+s;
  o->writeEntry(s);
  //while (o->listCells.size()<=o->cellNum) o->listCells<<"";
  //o->listCells[o->cellNum]=cellName;
  o->hashList.insert(cellName,o->cellNum);
  o->cellNum++;
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveCIF(o);
        }
    }
    saved=true;
  s="DF";
  o->writeEntry(s);
}

void cell::saveSOURCE(source *o){
}

void cell::saveCSV(csv *o){

  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveCSV(o);
        }
    }
    saved=true;
}

void cell::saveGerber(gerber *g){
elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveGerber(g);
        }
    }
}



void cell::rotateSelect(double angle ,QPoint pos) {
    paintInfoClear();
    strans m;
    m.translate(pos.x(),pos.y());
    m.rotate(angle);
    m.translate(-pos.x(),-pos.y());
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            if ((f->thisElement->isBox())&&(f->thisElement->select)) {
                polygon *p=f->thisElement->convertToPolygon();
                p->map(m);
                box *b=p->convertToBox();
                delete f->thisElement;
                if (b!=NULL) {
                    f->thisElement=b;
                    delete p;
                } else {
                    f->thisElement=p;
                }
                f->thisElement->select=true;
            } else {
                f->thisElement->mapSelect(m);//,true);
            }
        }
    }
}

void cell::mapSelect(strans t){
 paintInfoClear();

    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if ((f->thisElement!=NULL)&&(f->thisElement->select)) {

                f->thisElement->mapSelect(t);//,true);
        }
    }
}

void cell::scaleSelect(QPoint pos,QPoint p2,QPoint p3){
    paintInfoClear();
    strans m;
    m.translate(pos.x(),pos.y());
    double x=double(p3.x()-pos.x())/double(p2.x()-pos.x());
    double y=double(p3.y()-pos.y())/double(p2.y()-pos.y());
    if (x==0)x=1;
    if (y==0)y=1;
    if ((p2.x()-pos.x())==0)x=1;
    if ((p2.y()-pos.y())==0)y=1;
    m.scale(x,y);
    m.translate(-pos.x(),-pos.y());
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            if ((f->thisElement->isBox())&&(f->thisElement->select)) {
                polygon *p=f->thisElement->convertToPolygon();
                p->map(m);
                box *b=p->convertToBox();
                delete f->thisElement;
                if (b!=NULL) {
                    f->thisElement=b;
                    delete p;
                } else {
                    f->thisElement=p;
                }
                f->thisElement->select=true;
            } else {
                f->thisElement->mapSelect(m);
            }
        }
    }
}

void cell::mirrorSelect(QPoint p1 ,QPoint p2) {
    paintInfoClear();
    strans m;
    if (p1==p2) {
	m.translate(p1.x(),p1.y());
        m.scale((-1));
        m.translate(-p1.x(),-p1.y());
    } else {
        double angle;
        if ((p1.x()-p2.x())==0) {
            angle=90;
        } else {
            angle=atan((double)(p1.y()-p2.y())/(double)(p1.x()-p2.x()))/2/M_PI*360;
        }
        m.translate(p1.x(),p1.y());
        m.rotate(angle);
        m.toggleMirror_x();
        m.rotate(-angle);
        m.translate(-p1.x(),-p1.y());
    }
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            if ((f->thisElement->isBox())&&(f->thisElement->select)) {
                polygon *p=f->thisElement->convertToPolygon();
                p->map(m);
                box *b=p->convertToBox();
                delete f->thisElement;
                if (b!=NULL) {
                    f->thisElement=b;
                    delete p;
                } else {
                    f->thisElement=p;
                }
                f->thisElement->select=true;
            } else {
                f->thisElement->mapSelect(m);
            }
        }
    }
}

void cell::triangulateSelect(int layer){
 elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    if (f->thisElement->select)
	    if (f->thisElement->isPolygon()){
		QList<pointArray> pa=f->thisElement->getPoints().triangulate();
		if (pa.size()>1)
		for (int i=0;i<pa.size();i++){
			addPolygon(pa[i],layer);
			}
		}
        }
}

void cell::flatSelect() {
    elementList *f,*e;
    elementList *a,*c;
    a=NULL;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            e=f->thisElement->flatSelect();
            if (e!=NULL) {
                for (c=e;c->nextElement!=NULL;c=c->nextElement) {}
                c->nextElement=a;
                a=e;
                delete f->thisElement;
                f->thisElement=NULL;
            }
		else if (f->thisElement->select) if ((f->thisElement->isCellref())|| (f->thisElement->isCellrefArray())){
		     delete f->thisElement;
                     f->thisElement=NULL;
		}
            ;
        }
    }
    if (firstElement!=NULL) {
        for (f=firstElement;f->nextElement!=NULL;f=f->nextElement) {}
        f->nextElement=a;
    }
    else {firstElement=a;}
    clean();
}

void cell::flatAllSelect() {
    elementList *f,*e;
    elementList *a,*c;
    do {
    a=NULL;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            e=f->thisElement->flatSelect();
            if (e!=NULL) {
                for (c=e;c->nextElement!=NULL;c=c->nextElement) {}
                c->nextElement=a;
                a=e;
                delete f->thisElement;
                f->thisElement=NULL;
            }
		else if (f->thisElement->select)if ((f->thisElement->isCellref())|| (f->thisElement->isCellrefArray())){
		     delete f->thisElement;
                     f->thisElement=NULL;
		}
            ;
        }
    }
    if (firstElement!=NULL) {
        for (f=firstElement;f->nextElement!=NULL;f=f->nextElement) {}
        f->nextElement=a;
    }
    else {firstElement=a;}
    clean();}
   while (a!=NULL);
}


void cell::group(cell * cell_) {
    elementList *f;
    elementList *a=cell_->firstElement;
    elementList *b;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL)
            if (f->thisElement->select) {
                b=new elementList();
                b->nextElement=a;
                b->thisElement=f->thisElement;
                a=b;
                f->thisElement=NULL;
            }
    }

    clean();
    cell_->firstElement=a;
}

int cell::groupStructure(cell *cell_){
int num=0;
if (cell_==NULL) return 0;
if (cell_->firstElement==NULL) return 0;
deselectAll();
elementList *e1=cell_->firstElement;
if (e1->thisElement==NULL) return 0;
elementList *e2=firstElement;
while (e2!=NULL){
	if (e2->thisElement!=NULL){
		if (e2->thisElement->identicalStructure(e1->thisElement)){
			e2->thisElement->selectAll();
			QPoint pos_e1(INT_MAX,INT_MAX);
			QPoint pos_e2(INT_MAX,INT_MAX);
			e2->thisElement->minimum(&pos_e2);
			e1->thisElement->minimum(&pos_e1);
			QPoint off=-pos_e1+pos_e2;
			//search rest elements
			elementList *e3=e1->nextElement;
			bool found=true;
			while (found&&(e3!=NULL)){
				elementList *e4=firstElement;
				element *eMatch;
				if (e3->thisElement!=NULL){
					eMatch=e3->thisElement->copy();
					/*if (e3->thisElement->isBox())eMatch=new box(e3->thisElement->getBox());
					else if (e3->thisElement->isPath())eMatch=new path(e3->thisElement->getPath());
					else if (e3->thisElement->isPolygon())eMatch=new polygon(e3->thisElement->getPolygon());
					else if (e3->thisElement->isCellref())eMatch=new cellref(e3->thisElement->getCellref());
					else if (e3->thisElement->isCellrefArray())eMatch=new cellrefArray(e3->thisElement->getCellrefArray());
					else if (e3->thisElement->isText())eMatch=new txt(e3->thisElement->getText());
					else eMatch=new element();*/
					eMatch->move(off);
					//printf("check %d\n",e3->thisElement);
					bool found2=false;
					while (!found2&&(e4!=NULL)){
						if (e4->thisElement!=NULL){
							if (e4->thisElement->identical(eMatch)){
								found2=true;
								//printf("found %d\n",e4->thisElement);
								e4->thisElement->selectAll();
							}
						}
						e4=e4->nextElement;
					}
					if (!found2) found=false;
					delete eMatch;
				}
				e3=e3->nextElement;
			}
			if (found){
			num++;
			//found + insert cellref
			addCellref(cell_,off);
			//delete selected elements;
			 elementList *f;
             for (f=firstElement;f!=NULL;f=f->nextElement) {
				if (f->thisElement!=NULL) {
					if (f->thisElement->select==true) {
						delete f->thisElement;
						f->thisElement=NULL;
					} 
				}
			}
			}
			else {
				deselectAll();
			}
		}
	}
	e2=e2->nextElement;
}
clean();
return num;
}

void cell::cutSelect(QPoint p1, QPoint p2) {
    elementList *f;
    elementList *a=NULL;
    elementList *d,*c=NULL;
    if (firstElement!=NULL){
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            if ((f->thisElement->isBox())&&(f->thisElement->select)) {
                polygon *p=f->thisElement->convertToPolygon();
                p->select=true;
                c=p->cutSelect(p1,p2);
                box *b=p->convertToBox();
                delete f->thisElement;
                if (b==NULL) {
                    f->thisElement=p;
                } else {
                    delete p;
                    b->select=true;
                    f->thisElement=b;
                }
            } else {
                c=f->thisElement->cutSelect(p1,p2);
            }
        }
        if (c!=NULL) {
            for (d=c;d->nextElement!=NULL;d=d->nextElement) {}
            d->nextElement=a;
            a=c;
        }
    }
    for (f=firstElement;f->nextElement!=NULL;f=f->nextElement) {}
    f->nextElement=a;
    clean();}
}

void cell::mergeSelect() {
    elementList *f,*e;
    polygon *p;
    path *pa;
    element *q;
    box *b_;
    bool b;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
     if (f->thisElement!=NULL) if (f->thisElement->select)
        for (e=f->nextElement;e!=NULL;e=e->nextElement) {
            if ((f->thisElement!=NULL)&&(e->thisElement!=NULL)&&(e!=f)) {
                if (f->thisElement->select){
		//printf("%d %d\n",f->thisElement,e->thisElement);
                  if ((f->thisElement->isBox())) {
                    		q=f->thisElement->convertToPolygon();
                    		q->select=true;
                	} else if ((f->thisElement->isPolygon())) {
                    		q=f->thisElement;
                	} else
                    		q=NULL;
		  if (e->thisElement->select) {
                	if ((e->thisElement->isBox())) {
                    			p=e->thisElement->convertToPolygon();
                    			p->select=true;
                		} else if ((e->thisElement->isPolygon())) {
                    			p=new polygon(e->thisElement->getPolygon());
                		} else
                    			p=NULL;
                	if ((p!=NULL)&&(q!=NULL)) {
                    			b=q->mergeSelect(p);
                    			if (b) {
                        			delete p;
                        			delete e->thisElement;
                        			e->thisElement=NULL;
                        			e=firstElement;
                        			if (f->thisElement->isBox()) {
                            				b_=q->convertToBox();
                            				if (b_!=NULL) {
                                				b_->select=true;
                                				delete f->thisElement;
                                				f->thisElement=b_;
                                				delete q;
                                				q=NULL;
                            				} else {
                                				delete f->thisElement;
                               					 f->thisElement=q;
                            					}
                        				}
                    				} else {
                        				delete p;
                        				if (f->thisElement->isBox()) {
                            					delete q;
                        					}
                   		 			}
                			}
			// merge path elelments
			if ((f->thisElement->isPath())&&(e->thisElement->isPath())&&(e!=f)){
					pa=e->thisElement->getPath();
					b=f->thisElement->mergeSelect(pa);
					if (b) {
				 		delete e->thisElement;
				 		e->thisElement=NULL;
						e=firstElement;
						f->thisElement->clean();
						}
					}
				}
			}
            	}
        }
    }
    clean();
}

cell * cell::copy() {
    cell *c=new cell();
    c->cellName=cellName;
    c->date_access=date_access;
    c->date_modification=date_modification;
    c->time_access=time_access;
    c->time_modification=time_modification;
    c->cellData=cellData;
    elementList *f,*a,*b;
    element *e=NULL;
    a=NULL;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
			e=f->thisElement->copy();
            /*if (f->thisElement->isBox()) {
                e=new box(f->thisElement->getBox());
                ;
            }
            if (f->thisElement->isPolygon()) {
                e=new polygon((f->thisElement->getPolygon()));
            }
            if (f->thisElement->isCellrefArray()) {
                e=new cellrefArray(f->thisElement->getCellrefArray());
            }
            if (f->thisElement->isCellref()) {
                e=new cellref(f->thisElement->getCellref());
		}
	    if (f->thisElement->isText()) {
                e=new txt(f->thisElement->getText());
		}
	    if (f->thisElement->isPath()) {
                e=new path(f->thisElement->getPath());
            }
            if (e==NULL) {
                e=new element();
                *e=*f->thisElement;
            }*/
            b=new elementList();
            b->thisElement=e;
            b->nextElement=a;
            a=b;
            e=NULL;
        }
        ;
    }
    c->firstElement=a;
    return c;
}

void cell::nextPoint() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->nextPoint();
        }
    }
}

void cell::cleanElements() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->clean();
        }
    }
}

void cell::roundSelect(int i) {
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->roundSelect(i);
        }
    }
}

void cell::snapShapeSelect(int i) {
    paintInfoClear();
    QHash<int,QPoint> hash;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->snapSelectGet(&hash);
        }
    }
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->snapSelectSnap(&hash,i);
        }
    }
}

void cell::edgeRemoveSelect(int i) {
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->edgeRemoveSelect(i);
        }
    }
}

void cell::cropSharpAnglesSelect(int i){
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->cropSharpAnglesSelect(i);
        }
    }
}

double cell::areaSelect() {
    elementList *f;
    double a=0;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            a+=f->thisElement->areaSelect();
        }
    }
    return a;
}

double cell::areaSelected() {
    elementList *f;
    double a=0;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            a+=f->thisElement->areaSelected();
        }
    }
    return a;
}

double cell::circumferenceSelect(){
    elementList *f;
    double a=0;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            a+=f->thisElement->circumferenceSelect();
        }
    }
    return a;
}

double cell::circumferenceSelected(){
    elementList *f;
    double a=0;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            a+=f->thisElement->circumferenceSelected();
        }
    }
    return a;
}

void cell::invertSelect(){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->invertSelect();
        }
    }
}

void cell::selectAll() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->selectAll();
        }
    }
}

void cell::selectVisible() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->selectVisible();
        }
    }
}

void cell::deselectAll() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->deselectAll();
        }
    }
}

void cell::selectLayer(int layer){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->selectLayer(layer);
        }
    }
}

void cell::deselectLayer(int layer){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->deselectLayer(layer);
        }
    }
}

elementList* cell::nearestElement(QPoint p) {
    double dis=1.1E99;
    double d;
    elementList *e=NULL;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            d=f->thisElement->nearestDistance(p);
            if (d<dis) {
                dis=d;
                e=f;
            }
	    else if (d==dis){
	      if(f->thisElement->pointInsideElement(p)){
		dis=d;
                e=f;
	      }
	    }
        }
    }
    return e;
}

elementList* cell::nearestElement(QPoint p,QPoint *point) {
    double dis=1.1E99;
    double d;
    elementList *e=NULL;
    elementList *f;
    QPoint ph;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            d=f->thisElement->nearestDistancePoint(p,&ph);
            if (d<dis) {
                dis=d;
                e=f;
		*point = ph;
            }
	    else if (d==dis){
	      if(f->thisElement->pointInsideElement(p)){
		dis=d;
                e=f;
		*point = ph;
	      }
	    }
        }
    }
    return e;
}

elementList* cell::nearestForm(QPoint p){
    double dis=1.1E99;
    double d;
    elementList *e=NULL;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	  if ((f->thisElement->isPolygon())||(f->thisElement->isBox()||(f->thisElement->isText())||(f->thisElement->isPath()))){
            d=f->thisElement->nearestDistance(p);
            if (d<dis) {
                dis=d;
                e=f;
            }
	    else if (d==dis){
	      if(f->thisElement->pointInsideElement(p)){
		dis=d;
                e=f;
	      }
	    }
	    
        }
    }
    return e;
}

elementList* cell::nearestCell(QPoint p){
double dis=1.1E99;
    double d;
    elementList *e=NULL;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	  if ((f->thisElement->isCellref())||(f->thisElement->isCellrefArray())){
            d=f->thisElement->nearestDistance(p);
            if (d<dis) {
                dis=d;
                e=f;
            }
        }
    }
    return e;
}

elementList* cell::nearestCell(QPoint p,QList<element*> exclude){
double dis=1.1E99;
    double d;
    elementList *e=NULL;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if ((f->thisElement!=NULL) &&(!exclude.contains(f->thisElement)))
	  if ((f->thisElement->isCellref())||(f->thisElement->isCellrefArray())){
            d=f->thisElement->nearestDistance(p);
            if (d<dis) {
                dis=d;
                e=f;
            }
        }
    }
    return e;
}


elementList* cell::nearestPointVirtual(QPoint p,QPoint *point){
	if (element::distance(p,*point)<(1<<20)){
			QPoint p1,p2;
			uint j;
			paintInfoGet(&p1,&p2,&j);
			int i=(int)element::distance(p,*point);
			if (p2.x()+i<p.x()) return NULL;
			if (p1.x()-i>p.x()) return NULL;
			if (p2.y()+i<p.y()) return NULL;
			if (p1.y()-i>p.y()) return NULL;
	};
    double dis=1.1E99;
    double d;
    QPoint p_;
    elementList *e=NULL;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
		if (f->thisElement!=NULL) {
	  {
            d=f->thisElement->nearestDistance(p,&p_);
            if (d<dis) {
                dis=d;
                e=f;
		*point=p_;
            }
	  }}
    }
    return e;
}

elementList* cell::nearestPoint(QPoint p,QPoint *point){
	if (element::distance(p,*point)<(1<<20)){
			QPoint p1,p2;
			uint j;
			paintInfoGet(&p1,&p2,&j);
			int i=(int)element::distance(p,*point);
			if (p2.x()+i<p.x()) return NULL;
			if (p1.x()-i>p.x()) return NULL;
			if (p2.y()+i<p.y()) return NULL;
			if (p1.y()-i>p.y()) return NULL;
	};
    double dis=1.1E99;
    double d;
    QPoint p_;
    elementList *e=NULL;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
		if (f->thisElement!=NULL) {
	  if ((f->thisElement->isPolygon())||(f->thisElement->isBox()||(f->thisElement->isText())||(f->thisElement->isPath()))) {
            d=f->thisElement->nearestDistance(p,&p_);
            if (d<dis) {
                dis=d;
                e=f;
		*point=p_;
            }
	  }}
    }
    return e;
}

elementList* cell::identicalPoint(elementList *elem,QPoint point){
    double d;
    QPoint p_;
    elementList *e=elem->nextElement;
    if (e==NULL){e=firstElement;}
    elementList *f;
    for (f=e;f!=elem;) {
        if (f->thisElement!=NULL) 
	  if ((f->thisElement->isPolygon())||(f->thisElement->isBox()||(f->thisElement->isText())||(f->thisElement->isPath()))){
            d=f->thisElement->nearestDistance(point,&p_);
            if (p_==point) {return f; }
        }
	f=f->nextElement;
	if (f==NULL) f=firstElement;
    }
    return elem;
}

elementList* cell::identicalElementPoint(elementList *elem,QPoint point){
	double d;
    QPoint p_;
    elementList *e=elem->nextElement;
    if (e==NULL){e=firstElement;}
    elementList *f;
    for (f=e;f!=elem;) {
        if (f->thisElement!=NULL) 
	    {
            d=f->thisElement->nearestDistancePoint(point,&p_);
            if (p_==point) {return f; }
        }
	f=f->nextElement;
	if (f==NULL) f=firstElement;
    }
    return elem;
}

QPoint cell::nearestPoint(QPoint p, int searchradius){
    QPoint point;
    point=QPoint(INT_MAX,INT_MAX);
    if (statusPaintInfo==0) paintInfoCalc();
    if (p.x()+searchradius<paintInfoMin.x()) return point;
    if (p.x()-searchradius>paintInfoMax.x()) return point;
    if (p.y()+searchradius<paintInfoMin.y()) return point;
    if (p.y()-searchradius>paintInfoMax.y()) return point;
    nearestPointVirtual(p,&point);
    return point;
}

QPoint cell::nearestLine(QPoint p, int searchradius){
   double dis=1.1E99;
    double d=dis;
    QPoint p_,point;
    point=QPoint(INT_MAX,INT_MAX);
    if (statusPaintInfo==0) paintInfoCalc();
    if (p.x()+searchradius<paintInfoMin.x()) return point;
    if (p.x()-searchradius>paintInfoMax.x()) return point;
    if (p.y()+searchradius<paintInfoMin.y()) return point;
    if (p.y()-searchradius>paintInfoMax.y()) return point;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
            d=f->thisElement->nearestLine(p,&p_,searchradius);
            if (d<dis) {
                dis=d;
		point=p_;
            }
    }
return point;
}
QPoint cell::nearestMiddleLine(QPoint p, int searchradius){
    double dis=1.1E99;
    double d=dis;
    QPoint p_,point;
    point=QPoint(INT_MAX,INT_MAX);
    if (statusPaintInfo==0) paintInfoCalc();
    if (p.x()+searchradius<paintInfoMin.x()) return point;
    if (p.x()-searchradius>paintInfoMax.x()) return point;
    if (p.y()+searchradius<paintInfoMin.y()) return point;
    if (p.y()-searchradius>paintInfoMax.y()) return point;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
            d=f->thisElement->nearestMiddle(p,&p_,searchradius);
            if (d<dis) {
                dis=d;
		point=p_;
            }
    }
return point;
}
QPoint cell::nearestCenter(QPoint p, int searchradius){
    double dis=1.1E99;
    double d=dis;
    QPoint p_,point;
    point=QPoint(INT_MAX,INT_MAX);
    if (statusPaintInfo==0) paintInfoCalc();
    if (p.x()+searchradius<paintInfoMin.x()) return point;
    if (p.x()-searchradius>paintInfoMax.x()) return point;
    if (p.y()+searchradius<paintInfoMin.y()) return point;
    if (p.y()-searchradius>paintInfoMax.y()) return point;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
            d=f->thisElement->nearestCenter(p,&p_,searchradius);
            if (d<dis) {
                dis=d;
		point=p_;
            }
    }
return point;
}

QPoint cell::nearestIntersection(QPoint p, int searchradius){
  elementList *f1,*f2;
  double dis=1.1E99;
  QPoint point;
  point=QPoint(INT_MAX,INT_MAX);
  if (statusPaintInfo==0) paintInfoCalc();
  if (p.x()+searchradius<paintInfoMin.x()) return point;
  if (p.x()-searchradius>paintInfoMax.x()) return point;
  if (p.y()+searchradius<paintInfoMin.y()) return point;
  if (p.y()-searchradius>paintInfoMax.y()) return point;
  elementList *fhelp=NULL;
int count=0;
  for (f1=firstElement;f1!=NULL;f1=f1->nextElement) {
	if (f1->thisElement!=NULL) 
		if ((f1->thisElement->isPolygon())||(f1->thisElement->isBox()|| (f1->thisElement->isPath())))
			{
			bool possible=true;
			QPoint pmin,pmax;
			pmin=QPoint(INT_MAX,INT_MAX);
			pmax= QPoint(INT_MIN,INT_MIN);
			uint count_;
			f1->thisElement->paintInfo(&pmin,&pmax,&count_);
			if (p.x()+searchradius<pmin.x()) possible=false;
  			if (p.x()-searchradius>pmax.x()) possible=false;
  			if (p.y()+searchradius<pmin.y()) possible=false;
  			if (p.y()-searchradius>pmax.y()) possible=false;
			if (possible&&(count<512)){
				count++;
				//f1->thisElement->select=true;
				elementList *help=new elementList;
				help->thisElement=f1->thisElement;
				help->nextElement=fhelp;
				fhelp=help;
				}
			}
	}
  //printf("inter count %d\n",count);
  pointArray p1,p2;
  QPoint p_;

  for (f1=fhelp;f1!=NULL;) 
         {
		p1=f1->thisElement->getPoints();
		if (p1.size()>1)
		   for (f2=f1->nextElement;f2!=NULL;f2=f2->nextElement) 
			if (f2->thisElement!=NULL) {
				p2=f2->thisElement->getPoints();
				if (p2.size()>1){
					for(int i1=0;i1<p1.size()-1;i1++){
						/*bool b=false;
						if ((p1.point(i1).x()<p.x())&&(p.x()<p1.point(i1+1).x())) {b=true;}
						if ((p1.point(i1).x()>p.x())&&(p.x()>p1.point(i1+1).x())) {b=true;}
						if ((p1.point(i1).y()<p.y())&&(p.y()<p1.point(i1+1).y())) {b=true;}
						if ((p1.point(i1).y()>p.y())&&(p.y()>p1.point(i1+1).y())) {b=true;}
						if (b)*/ for (int i2=0;i2<p2.size()-1;i2++){
							/*bool c=false;
							if ((p2.point(i2).x()<p.x())&&(p.x()<p2.point(i2+1).x())) {c=true;}
							if ((p2.point(i2).x()>p.x())&&(p.x()>p2.point(i2+1).x())) {c=true;}
							if ((p2.point(i2).y()<p.y())&&(p.y()<p2.point(i2+1).y())) {c=true;}
							if ((p2.point(i2).y()>p.y())&&(p.y()>p2.point(i2+1).y())) {c=true;}
								if (c)*/ {
									QPoint pc; 
									if(element::cutPoint2(p1.point(i1),p1.point(i1+1),p2.point(i2),p2.point(i2+1),&pc)){
										double d=element::distance(pc,p);
										if (d<dis) {dis=d;p_=pc;}
									}
									
								}
							}
					}
				}
			}
		elementList *fh=f1;
		f1=f1->nextElement;
		fh->thisElement=NULL;
		fh->nextElement=NULL;
		delete fh;
		}
//printf("inter count %d\n",count);
  return p_;
}



elementCount cell::countSelect() {
elementCount c;
c.points=0;
c.path=0;
c.box=0;
c.polygon=0;
c.cellref=0;
c.cellrefarray=0;
c.text=0;

    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->countSelect(&c);
        }
    }
 return c;
}

 bool cell::useLayer(int layer){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            if (f->thisElement->useLayer(layer)) return true;
        }
    }
 return false;
 }

void cell::useLayer(QBitArray *b){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->useLayer(b);
        }
    }
}

void cell::swapLayer(int i,int k){
  elementList *l=firstElement;
  while (l!=NULL) {
     if (l->thisElement!=NULL) {
  	if (l->thisElement->layerNum==i)
  		l->thisElement->layerNum=k;
	else if (l->thisElement->layerNum==k)
  		l->thisElement->layerNum=i;
    } 
    l=l->nextElement;
  }
}

void cell::swapLayerSelect(int i,int k){
  elementList *l=firstElement;
  while (l!=NULL) {
     if (l->thisElement!=NULL)
        if (l->thisElement->select) {
  	   if (l->thisElement->layerNum==i)
  		l->thisElement->layerNum=k;
	   else if (l->thisElement->layerNum==k)
  		l->thisElement->layerNum=i;
    } 
    l=l->nextElement;
  }
}

void cell::pathSelectVisible() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isPath()){
            f->thisElement->selectVisible();
        }
    }
}

void cell::pathDeselect() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isPath()){
            f->thisElement->deselectAll();
        }
    }
}

void cell::boxSelectVisible() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isBox()){
            f->thisElement->selectVisible();
        }
    }
}

void cell::boxDeselect() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isBox()){
            f->thisElement->deselectAll();
        }
    }
}
void cell::polygonSelectVisible() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isPolygon()){
            f->thisElement->selectVisible();
        }
    }
}

void cell::polygonDeselect() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isPolygon()){
            f->thisElement->deselectAll();
        }
    }
}
void cell::textSelectVisible() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isText()){
            f->thisElement->selectVisible();
        }
    }
}


void cell::selectText(QString t){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isText()){
	    if (f->thisElement->getName()==t)
            	f->thisElement->selectVisible();
        }
    }
}

void cell::deselectText(QString t){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isText()){
	    if (f->thisElement->getName()==t)
            	f->thisElement->deselectAll();
        }
    }
}

void cell::textDeselect() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isText()){
            f->thisElement->deselectAll();
        }
    }
}

void cell::selectCellref(QString cellname){
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
		cell *c=f->thisElement->depend();
	if (c!=NULL){
		//printf("%s\n",c->cellName.toAscii().data());
		if (c->cellName==cellname) f->thisElement->selectAll();
		}
        }
    }
}

void cell::toBoxSelect(){
   elementList *f;
box *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isPolygon()&&f->thisElement->select){
	    p=f->thisElement->convertToBox();
	    if (p!=NULL) {
		p->select=true;
		delete f->thisElement;
            	f->thisElement=p;
		}
        }
    }
}

void cell::toPolygonSelect(){
elementList *f,*el,*help;
polygon *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
	    if (f->thisElement->isBox()&&f->thisElement->select){
	    	p=f->thisElement->convertToPolygon();
	    	if (p!=NULL) {
			p->select=true;
			delete f->thisElement;
            		f->thisElement=p;
			}
        	}
	    else if(f->thisElement->isPath()&&f->thisElement->select) {
		p=f->thisElement->convertToPolygon();
	    	if (p!=NULL) {
			p->select=true;
			delete f->thisElement;
            		f->thisElement=p;
			}
		}
	    else if(f->thisElement->isText()&&f->thisElement->select) {
		el=f->thisElement->convertText();
	    	if (el!=NULL) {
			delete f->thisElement;
            		f->thisElement=NULL;
			help=firstElement;
			firstElement=el;
			while (el->nextElement!=NULL) {  
				el->thisElement->select=true;
				el=el->nextElement;
			}
			el->thisElement->select=true;
			el->nextElement=help;
			}
		}
	}
    }
  clean();
}

void cell::toCircleSelect(){
paintInfoClear();
elementList *f;
polygon *p,*p2;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    if (f->thisElement->isBox()&&f->thisElement->select){
	    	p=f->thisElement->convertToPolygon();
	    	if (p!=NULL) {
			p2=p->convertToCircle();
			delete f->thisElement;
			delete p;
			p2->select=true;
            		f->thisElement=p2;
			}
        	}
	    if (f->thisElement->isPolygon()&&f->thisElement->select){
	    	p=f->thisElement->convertToCircle();
	    	if (p!=NULL) {
			p->select=true;
			delete f->thisElement;
            		f->thisElement=p;
			}
        	}
    }
}


void cell::toMeshSelect(int width,int spaceing){
    elementList *f,*e;
    elementList *a,*c;
    a=NULL;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            e=f->thisElement->convertToMesh(width,spaceing);
            if (e!=NULL) {
                for (c=e;c->nextElement!=NULL;c=c->nextElement) {}
                c->nextElement=a;
                a=e;
                delete f->thisElement;
                f->thisElement=NULL;
            }
            ;
        }
    }
    if (firstElement!=NULL) {
        for (f=firstElement;f->nextElement!=NULL;f=f->nextElement) {}
        f->nextElement=a;
    }
    else {firstElement=a;}
    clean();
}

void cell::closeToPolygonSelect(){
elementList *f;
polygon *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    if(f->thisElement->isPath()&&f->thisElement->select) {
		p=f->thisElement->closeToPolygon();
	    	if (p!=NULL) {
			p->select=true;
			delete f->thisElement;
            		f->thisElement=p;
			}
		}
    }
  clean();
}

void cell::convertToPolygonIfClosedSelect(){
elementList *f;
polygon *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    if(f->thisElement->isPath()&&f->thisElement->select) {
		p=f->thisElement->convertToPolygonIfClosed();
	    	if (p!=NULL) {
			p->select=true;
			delete f->thisElement;
            		f->thisElement=p;
			}
		}
    }
  clean();
}

void cell::convertToPolygonIfClosed(){
elementList *f;
polygon *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    if(f->thisElement->isPath()) {
		p=f->thisElement->convertToPolygonIfClosed();
	    	if (p!=NULL) {
			p->select=f->thisElement->select;
			delete f->thisElement;
            		f->thisElement=p;
			}
		}
    }
  clean();
}


void cell::closeToPolygon(){
elementList *f;
polygon *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    if(f->thisElement->isPath()) {
		p=f->thisElement->closeToPolygon();
	    	if (p!=NULL) {
			p->select=f->thisElement->select;
			delete f->thisElement;
            		f->thisElement=p;
			}
		}
    }
  clean();
}

void cell::toBox(){
elementList *f;
box *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->isPolygon()){
	    p=f->thisElement->convertToBox();
	    if (p!=NULL) {
		if (f->thisElement->select) p->select=true;
		delete f->thisElement;
            	f->thisElement=p;
		}
        }
    }
}

void cell::toPolygon(){
elementList *f,*el,*help;
polygon *p;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
	    if (f->thisElement->isBox()){
	    	p=f->thisElement->convertToPolygon();
	    	if (p!=NULL) {
			if (f->thisElement->select) p->select=true;
			delete f->thisElement;
            		f->thisElement=p;
			}
        	}
	    else if(f->thisElement->isPath()) {
		p=f->thisElement->convertToPolygon();
	    	if (p!=NULL) {
			if (f->thisElement->select) p->select=true;
			delete f->thisElement;
            		f->thisElement=p;
			}
		}
	    else if(f->thisElement->isText()) {
		el=f->thisElement->convertText();
	    	if (el!=NULL) {
			bool sel=f->thisElement->select;
			delete f->thisElement;
            		f->thisElement=NULL;
			help=firstElement;
			firstElement=el;
			while (el->nextElement!=NULL) {
				if (sel) el->thisElement->select=true;
				el=el->nextElement;
			}
			if (sel) el->thisElement->select=true;
			el->nextElement=help;
			}
		}
	}
    }
 clean();
}

void cell::setWidthSelect(int w){
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->select){
	    f->thisElement->setWidth(w);
        }
    }
}

void cell::setCapSelect(int w){
    paintInfoClear();
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->select){
	    f->thisElement->setCap(w);
        }
    }
}

void cell::setDatatypeSelect(int w){
elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    f->thisElement->setDatatypeSelect(w);
    }
}

void cell::selectDatatype(int w){
elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    f->thisElement->selectDatatype(w);
    }
}

int cell::countElements(){
  int i=0;
  elementList *f;
    	for (f=firstElement;f!=NULL;f=f->nextElement) {
              i++;
	     if (i>900000) return 900000;
    	}
  return i;
}

void cell::paintInfoCalc(){
/*	erzeugt problem bei scale full
	if (firstElement==NULL){
		paintInfoMax=QPoint(0,0);
		paintInfoMin=QPoint(0,0);
		paintInfoElements=0;
		paintInfoCellElements=0;
		paintInfo=true;
		return;
		}*/
	QPoint paintIMax=QPoint(INT_MIN,INT_MIN);
	QPoint paintIMin=QPoint(INT_MAX,INT_MAX);	
	uint paintIElements=0;
	uint paintICellElements=0;
	defaultLayer=-2;
	elementList *f;
	for (f=firstElement;f!=NULL;f=f->nextElement) {
		if (f->thisElement!=NULL) {
		f->thisElement->paintInfo(&paintIMin,&paintIMax,&paintIElements);
		}
		++paintICellElements;
	}
	paintInfoMax=paintIMax;
	paintInfoMin=paintIMin;	
	paintInfoElements=paintIElements;
	paintInfoCellElements=paintICellElements;
	statusPaintInfo=1;
}

void cell::paintInfoMinMax(){
    if (statusPaintInfo==0) paintInfoCalc();
    QPoint paintIMax=QPoint(INT_MIN,INT_MIN);
    QPoint paintIMin=QPoint(INT_MAX,INT_MAX);	
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->minimum(&paintIMin);
            f->thisElement->maximum(&paintIMax);
		}
	}
	paintInfoMax=paintIMax;
	paintInfoMin=paintIMin;	
	statusPaintInfo=2;
}

void cell::paintInfoGet(QPoint *min,QPoint *max,uint *count){
if (statusPaintInfo==0) paintInfoCalc();
*min=paintInfoMin;
*max=paintInfoMax;
*count=paintInfoElements;
}

void cell::clearNodes(){
elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
	    f->thisElement->clearNode();
    }
}

void cell::moveOrigin(cell *c,QPoint pos){
    class cell  *cellhelp;
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            cellhelp=f->thisElement->depend();
            if (cellhelp==c) {
                f->thisElement->moveOrigin(pos);
            } 
        }
    }
    paintInfoClear();
}

void cell::clearNode() {
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->clearNode();
        }
    }
}

element* cell::addCircleBox(QPoint p1, QPoint p2,int layer){
	QPoint pc=(p1+p2)/2;
	QPoint pr=p1-p2;
	int r=abs(pr.x());
	if (abs(pr.y())<r) r=abs(pr.y());
	pr=pc+QPoint(r/2,0);
	pointArray pa=element::spirale(pc,pr,pr,setup::circularDefault);

	return addPolygon(pa,layer);
}

void cell::stripIdenticalElements(){
	deselectAll();
	elementList *f, *e;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) if (f->thisElement->select==false){
			for (e=f->nextElement;e!=NULL;e=e->nextElement){
				 if (e->thisElement!=NULL) if (e->thisElement->select==false)
					 if (e->thisElement->identical(f->thisElement)) e->thisElement->selectAll();
			}
        }
    }
	deleteSelect();
}

void cell::clearProperties()
{
	elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->property.clear();
        }
    }
}

int cell::findEdge(QPoint p1,QPoint p2,int layer,char dir){
	if (statusPaintInfo==0) paintInfoCalc();
	//p1,p2 suchbereich
	/*
	dir = 0 max x
	dir = 1 max y
	dir = 2	min x
	dir = 3 min y
	-> p1 max
	->p2 min
	if (!e->visibleBox(QPoint(paintInfoMax.x(),paintInfoMin.y()),QPoint(paintInfoMin.x(),paintInfoMax.y())))return;
	*/
	if (p1.x()<p2.x()){
		int x=p1.x();
		p1.setX(p2.x());
		p2.setX(x);
	}
	if (p1.y()<p2.y()){
		int y=p1.y();
		p1.setY(p2.y());
		p2.setY(y);
	}
	int result=0;
	switch (dir){
	case 0: result=p2.x();
		break;
	case 1: result=p2.y();
		break;
	case 2: result=p1.x();
		break;
	case 3: result=p1.y();
		break;
	}
	if (p1.x()<paintInfoMin.x())return result;
	if (p2.x()>paintInfoMax.x())return result;
	if (p1.y()<paintInfoMin.y())return result;
	if (p2.y()>paintInfoMax.y())return result;
	elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
		 if (f->thisElement!=NULL)
			 f->thisElement->findEdge(p1,p2,layer,dir,&result);
	}
	return result; 
}

void cell::lineDistanceLayer(QPoint p1,QPoint p2, int *left,int *right, int layer){
 if (statusPaintInfo==0) paintInfoCalc();
 int border= *left;
 if (*right>border) border= *right;
 QPoint min=p1;
 QPoint max=p2;
 if (p1.x()>max.x()) max.setX(p1.x());
 if (p1.y()>max.y()) max.setY(p1.y());
 if (p2.x()<min.x()) min.setX(p2.x());
 if (p2.y()<min.y()) min.setY(p2.y());
 min=min-QPoint(border,border);
 max=max+QPoint(border,border);
 if (max.x()<paintInfoMin.x())return ;
 if (min.x()>paintInfoMax.x())return ;
 if (max.y()<paintInfoMin.y())return ;
 if (min.y()>paintInfoMax.y())return ;
 elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
		 if (f->thisElement!=NULL)
			 f->thisElement->lineDistanceLayer(p1,p2,left,right, layer,min,max);
	}
	return ; 
}


bool cell::pointOnLayer(QPoint p,int layer){
 if (layer<0) return false;
 if (statusPaintInfo==0) paintInfoCalc();
 if (p.x()<paintInfoMin.x())return false;
 if (p.x()>paintInfoMax.x())return false;
 if (p.y()<paintInfoMin.y())return false;
 if (p.y()>paintInfoMax.y())return false;
 elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
		 if (f->thisElement!=NULL)
			 if (f->thisElement->pointOnLayer(p, layer)) return true;
	}
 return false;
}

void cell::flatCellrefArray(){
	deselectAll();
	elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
		 if (f->thisElement!=NULL)
			 if (f->thisElement->isCellrefArray()) f->thisElement->select=true;
	}
	flatSelect();
	deselectAll();
}

int cell::replaceText(QString text1,QString text2){
}

void cell::flatLayer(int layer) {
}

#ifdef netlistutility
#include "net/connectbuilder.h"
#endif

void cell::selectNode(int node){
#ifdef netlistutility
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
		if (f->thisElement->getNode()==node){
            	f->thisElement->selectAll();
        }
    }
#endif
}

void cell::deselectNode(int node){
#ifdef netlistutility
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
		if (f->thisElement->getNode()==node){
            	f->thisElement->deselectAll();
        }
    }
#endif
}

void cell::selectNodeOnLayer(int node,int layer){
#ifdef netlistutility
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
		if (f->thisElement->getNode()==node){
            		f->thisElement->selectLayer(layer);
        }
    }
#endif
}

void cell::deselectNodeOnLayer(int node,int layer){
#ifdef netlistutility
    elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) 
		if (f->thisElement->getNode()==node){
            		f->thisElement->deselectLayer(layer);
        }
    }
#endif
}

void cell::buildConnect(){
	if (firstElement==NULL) return;
	//printf("%s\n",cellName.toAscii().data());
	flatCellrefArray();
#ifdef netlistutility
	connectBuilder c(this);
	c.build();
#endif
}

#ifdef USE_3d
void cell::saveDXF3d(dxf3d* d){
  elementList *f;
    for (f=firstElement;f!=NULL;f=f->nextElement) {
        if (f->thisElement!=NULL) {
            f->thisElement->saveDXF3d(d);
        }
    }
    saved=true;
}
#endif

void cell::removeNotOrthogonalCellref(QHash<QString,cell*>hash ,drawingField*d){
}

void cell::removeScaledCellref(QHash<QString,cell*>hash ,drawingField*d){
}
