/***************************************************************************
 *   Copyright (C) 2005 by Juergen Thies                                   *
 *   layout@juergenthies.de                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "variant.h"
#include "general/errorreport.h"
#include "layout.h"
#include "keywords.h"
#include "general/drawingfield.h"
#include "elements/cell.h"
#include "elements/celllist.h"
#include <qstring.h>
#include <QStringList>
#include <qrect.h>
#include <qpoint.h>
#include "elements/pointarray.h"
#include "elements/element.h"
#include "elements/elementlist.h"
#include "macro/file.h"
#include "general/drc.h"
#ifdef netlistutility
#include "net/netlistmodule.h"
#include "net/netlist.h"
#include "net/netlistdevice.h"
#endif
#ifdef barcodeutility
#include "barcode/barcodemodule.h"
#endif
#ifdef backgroundutility
#include "background/backgroundmodule.h"
#endif
#include "macro.h"
#include "elements/layertranslator.h"
#ifdef SCHEMATIC
#include "schematic/schematic.h"
#include "schematic/schematicdisplay.h"
#include "schematic/sheetlist.h"
#include "schematic/sheet.h"
#include "schematic/elements/selementlist.h"
#endif
#ifdef TEXTEDIT
#include "textedit/textedit.h"
#include "textedit/textdisplay.h"
#endif
variant::variant()
{
data=NULL;
type=varVoid;
deleteAfter=true;
}

variant::variant(const variant &ret2){
   //printf("copy%d\n",ret2.data);
   type=ret2.type;
   data=ret2.data;
   deleteAfter=false;
   switch (type){
	case varInt:
		i=&int_;
		*i=*(ret2.i);
		deleteAfter=false;
	     	break;
	case varInt16:
		type=varInt;
		i=&int_;
		*i=(int)*(ret2.int16);
		break;
	case varInt32:
		type=varInt;
		i=&int_;
		*i=(int)*(ret2.int32);
		break;
	case varBool:
		b=&bool_;
		*b=*(ret2.b);
		deleteAfter=false;
	     	break;
	case varDouble:
		d=&double_;
		*d=*(ret2.d);
		deleteAfter=false;
	     	break;
	case varString:
		s=new QString();
		(*s)=(*ret2.s);
		deleteAfter=true;
	     	break;
	case varStringList:
		sl=new QStringList();
		(*sl)=(*ret2.sl);
		deleteAfter=true;
	     	break;
	case varLayerTranslator:
		LayerTranslator=new layerTranslator();
		(*LayerTranslator)=(*ret2.LayerTranslator);
		deleteAfter=true;
	    break;
	case varVoid:
		data=ret2.data;
		deleteAfter=false;
		break;
	case ptrElement:
	case ptrVoid:
	case ptrLayout:
#ifdef SCHEMATIC
	case ptrSchematic:
	case ptrSchematicDisplay:
	case ptrSheetList:
	case ptrSheet:
	case ptrSElement:
	case ptrSElementList:
#endif
#ifdef TEXTEDIT
	case ptrTextEdit:
	case ptrTextDisplay:
#endif
	case ptrCellList:
	case ptrDrawingField:
	case ptrCell:
	case ptrString:
	case ptrStringList:
	case ptrInt:
	case ptrDouble:
	case ptrBool:
	case ptrElementList:
	case ptrPoint:
	case ptrPointArray:
	case ptrRect:
	case ptrFile:
	case ptrDrc:
#ifdef netlistutility
	case ptrNetListModule:
	case ptrNetList:
	case ptrNetListDevice:
#endif
#ifdef barcodeutility
	case ptrBarcodeModule:
#endif
#ifdef backgroundutility
	case ptrBackgroundModule:
#endif
#ifdef USE_3d
	case ptrView3dModule:
#endif
	case ptrInt16:
	case ptrInt32:
	case ptrLayerTranslator:
		//printf("ptr\n");
		deleteAfter=false;
		break;
	case varCell:
		setType(varCell);
		*Cell= *ret2.Cell;
		deleteAfter=true;
		break;
	case varCellList:
		setType(varCellList);
		*CellList= *ret2.CellList;
		deleteAfter=true;
		break;
	case varRect:
		setType(varRect);
		*Rect= *ret2.Rect;
		deleteAfter=true;
		break;
	case varElement:
		setType(varElement);
		*Element= *ret2.Element;
		deleteAfter=true;
		break;
	case varElementList:
		setType(varElementList);
		*ElementList= *ret2.ElementList;
		deleteAfter=true;
		break;
	case varPoint:
		setType(varPoint);
		*Point= *ret2.Point;
		deleteAfter=true;
		break;
	case varPointArray:
		setType(varPointArray);
		*PointArray= *ret2.PointArray;
		deleteAfter=true;
		break;
	case varFile:
		setType(varFile);
		*File = *ret2.File;
		deleteAfter=true;
		break;
#ifdef netlistutility
	case varNetList:
		setType(varNetList);
		*NetList = *ret2.NetList;
		deleteAfter=true;
		break;
	case varNetListDevice:
		setType(varNetListDevice);
		*NetListDevice = *ret2.NetListDevice;
		deleteAfter=true;
		break;
#endif
#ifdef SCHEMATIC
	case varSElementList:
		setType(varSElementList);
		*SElementlist= *ret2.SElementlist;
		deleteAfter=true;
		break;
#endif
	case varDrc:
		throw 20;
		break;
	case varDrawingField:
		throw 20;
		break;
	/*default:
		throw 1;
		break;*/
	}
 //printf("end copy%d\n",data);
}
 
variant::~variant()
{
// printf("delete?%d\n",data);
deleteData();
//printf("enddelete%d\n",data);
}

void variant::deleteData(){
if (deleteAfter) {
   //printf("delete!%d\n",data);
   if (data!=NULL) {
   	switch (type){
	case varInt:
		delete i;
		break;
	case varBool:
		delete b;
		break;
	case varDouble:
		delete b;
		break;
	case varString:
		delete s;
		break;
	case varStringList:
		delete sl;
		break;
	case varCell:
		delete Cell;
		break;
	case varCellList:
		delete CellList;
		break;
	case varDrawingField:
		delete DrawingField;
		break;
	case varRect:
		delete Rect;
		break;
	case varElement:
		delete Element;
		break;
	case varElementList:
		delete ElementList;
		break;
	case varPoint:
		delete Point;
		break;
	case varPointArray:
		delete PointArray;
		break;
	case varFile:
		delete File;
		break;
	case varDrc:
		delete Drc;
		break;
	case varLayerTranslator:
		delete LayerTranslator;
		break;
#ifdef netlistutility
	case varNetList:
		delete NetList;
		break;
	case varNetListDevice:
		delete NetListDevice;
		break;
#endif
#ifdef SCHEMATIC
	case varSElementList:
		delete SElementlist;
		break;
#endif
	default:
		//printf("ptr\n");	
		break;
	}
   data=NULL;
   }
  }
}

void variant::setInt(int val){
  setType(varInt);
  int_=val;
}
void variant::setBool(bool val){
  setType(varBool);
  bool_=val;
}
void variant::setDouble(double val){
  setType(varDouble);
  double_=val;
}
void variant::setString(QString val){
  setType(varString);
  *s=val;
}

void variant::setPtrString(QString *val){
  setType(ptrString);
  s=val;
}

void variant::setStringList(QStringList val){
  setType(varStringList);
  *sl=val;
}

void variant::setPtrStringList(QStringList *val){
  setType(ptrStringList);
  sl=val;
}

int variant::getInt()const{
  switch (type){
	case varInt:
	case ptrInt:
		return (*i);
		break;
	case varInt16:
	case ptrInt16:
		return (int)(*int16);
		break;
	case varInt32:
	case ptrInt32:
		return (int)(*int32);
		break;
	case varBool:
	case ptrBool:
		return int(*b);
		break;
	case varDouble:
	case ptrDouble:
		return int(*d);
		break;
	case varString:
	case ptrString:
		return s->toInt();
		break;
	default:
		throw 23;	
		break;
	}
  return 0;
}

int* variant::getPtrInt() const{
  switch (type){
	case ptrInt:
	case varInt:
		return (i);
		break;
        default:
		throw 29;
		break;
	}
}

double variant::getDouble()const{
  switch (type){
	case varInt:
	case ptrInt:
		return double(*i);
		break;
	case varBool:
	case ptrBool:
		return double(*b);
		break;
	case varDouble:
	case ptrDouble:
		return (*d);
		break;
	case varString:
	case ptrString:
		return s->toDouble();
		break;
	default:
		throw 24;	
		break;
	}
  return 0;
}

double* variant::getPtrDouble() const{
  switch (type){
	case ptrDouble:
	case varDouble:
		return (d);
		break;
        default:
		throw 30;
		break;
	}
}

bool variant::getBool()const{
  switch (type){
	case varInt:
	case ptrInt:
		return bool(*i);
		break;
	case varBool:
	case ptrBool:
		return (*b);
		break;
	case varDouble:
	case ptrDouble:
		return bool(*d);
		break;
	case varString:
	case ptrString:
		return false;
		break;
	default:
		throw 25;	
		break;
	}
  return 0;
}

QString variant::getString()const{
 QString s1;
  switch (type){
	case varInt:
	case ptrInt:
		return s1.setNum((*i));
		break;
	case varBool:
	case ptrBool:
		if (*b) return "true";
		return "false";
		break;
	case varDouble:
	case ptrDouble:
		return s1.setNum((*d));
		break;
	case varString:
	case ptrString:
		return (*s);
		break;
	default:
		throw 22;
		break;
	}
  return 0;
}
QString* variant::getPtrString()const{
 QString s1;
  switch (type){
	case varString:
	case ptrString:
		return (s);
		break;
	default:
		throw 22;
		break;
	}
  return 0;
}

QStringList variant::getStringList()const{
  switch (type){
	case varStringList:
	case ptrStringList:
		return (*sl);
		break;
	default:
		throw 22;
		break;
	}
  return QStringList();
}
QStringList* variant::getPtrStringList()const{
  switch (type){
	case varStringList:
	case ptrStringList:
		return (sl);
		break;
	default:
		throw 22;
		break;
	}
  return 0;
}

layout* variant::getLayout()const{
 if ((type==ptrLayout)||(type==ptrVoid)) return Layout;
 throw 21;
}

#ifdef TEXTEDIT

    void variant::setPtrTextEdit(textEdit* l){
      setType(ptrTextEdit);
      TextEdit=l;
    }
    void variant::setTextEdit(textEdit l){
      setType(ptrTextEdit);
      TextEdit=&l;
    }
    textEdit* variant::getTextEdit() const{
       if ((type==ptrTextEdit)||(type==ptrVoid)) return TextEdit;
	throw 21;
    }
    void variant::setPtrTextDisplay(textDisplay* l){
      setType(ptrTextDisplay);
      TextDisplay=l;
    }
    void variant::setTextDisplay(textDisplay l){
      setType(ptrTextDisplay);
      TextDisplay=&l;
    }
    textDisplay* variant::getTextDisplay() const{
       if ((type==ptrTextDisplay)||(type==ptrVoid)) return TextDisplay;
	throw 21;
    }
#endif


#ifdef SCHEMATIC
schematic* variant::getSchematic()const{
 if ((type==ptrSchematic)||(type==ptrVoid)) return Schematic;
 throw 21;
}


schematicDisplay* variant::getSchematicDisplay() const{
 if ((type==ptrSchematicDisplay)||(type==ptrVoid)) return SchematicDisplay;
 throw 21;
}


sheetList* variant::getSheetList() const{
 if ((type==ptrSheetList)||(type==ptrVoid)) return SheetList;
 throw 21;
}

sheet* variant::getSheet() const{
 if ((type==ptrSheet)||(type==ptrVoid)) return Sheet;
 throw 21;
}


sElement* variant::getSElement() const{
 if ((type==ptrSElement)||(type==ptrVoid)) return SElement;
 throw 21;
}

#endif

cell* variant::getCell()const{
 if ((type==ptrCell)||(type==varCell)||(type==ptrVoid)) return Cell;
 throw 21;
}

cellList* variant::getCellList()const{
 if ((type==ptrCellList)||(type==varCellList)||(type==ptrVoid)) return CellList;
 throw 21;
}

drawingField* variant::getDrawingField()const{
 if ((type==ptrDrawingField)||(type==varDrawingField)||(type==ptrVoid)) return DrawingField;
 throw 21;
}
QPoint* variant::getPoint() const{
 if ((type==ptrPoint)||(type==varPoint)||(type==ptrVoid)) return Point;
 throw 21;
}
pointArray* variant::getPointArray() const{
 if ((type==ptrPointArray)||(type==varPointArray)||(type==ptrVoid)) return PointArray;
 throw 21;
}
QRect* variant::getRect() const{
 if ((type==ptrRect)||(type==varRect)||(type==ptrVoid)) return Rect;
 throw 21;
}
element* variant::getElement() const{
 if ((type==ptrElement)||(type==varElement)||(type==ptrVoid)) return Element;
 throw 21;
}
elementList* variant::getElementList() const{
 if ((type==ptrElementList)||(type==varElementList)||(type==ptrVoid)) return ElementList;
 throw 21;
}

drc* variant::getDrc() const{
 if ((type==ptrDrc)||(type==varDrc)||(type==ptrVoid)) return Drc;
 throw 21;
}

#ifdef netlistutility
 netListModule* variant::getNetListModule() const{
 if ((type==ptrNetListModule)||(type==ptrVoid)) return NetListModule;
 throw 21;
}
void variant::setPtrNetListModule(netListModule *d){
setType(ptrNetListModule);
NetListModule=d;
}

void variant::setPtrNetList(netList *d){
setType(ptrNetList);
NetList=d;
}

void variant::setNetList(netList d){
setType(varNetList);
*NetList=d;
}

netList* variant::getNetList()const{
 if ((type==ptrNetList)||(type==varNetList)||(type==ptrVoid)) return NetList;
 throw 21;
}

void variant::setPtrNetListDevice(netListDevice *d){
setType(ptrNetListDevice);
NetListDevice=d;
}

void variant::setNetListDevice(netListDevice d){
setType(varNetListDevice);
*NetListDevice=d;
}

netListDevice* variant::getNetListDevice()const{
 if ((type==ptrNetListDevice)||(type==varNetListDevice)||(type==ptrVoid)) return NetListDevice;
 throw 21;
}

#endif

#ifdef barcodeutility
 barcodeModule* variant::getBarcodeModule() const{
 if ((type==ptrBarcodeModule)||(type==ptrVoid)) return BarcodeModule;
 throw 21;
}
void variant::setPtrBarcodeModule(barcodeModule *d){
setType(ptrBarcodeModule);
BarcodeModule=d;
}

#endif

#ifdef backgroundutility
 backgroundModule* variant::getBackgroundModule() const{
 if ((type==ptrBackgroundModule)||(type==ptrVoid)) return BackgroundModule;
 throw 21;
}
void variant::setPtrBackgroundModule(backgroundModule *d){
setType(ptrBackgroundModule);
BackgroundModule=d;
}

#endif

#ifdef USE_3d
 view3dModule* variant::getView3dModule() const{
 if ((type==ptrView3dModule)||(type==ptrVoid)) return View3dModule;
 throw 21;
}
void variant::setPtrView3dModule(view3dModule *d){
setType(ptrView3dModule);
View3dModule=d;
}

#endif
void variant::setPtrDrc(drc *d){
setType(ptrDrc);
Drc=d;
}

void variant::setLayout(layout l){
setType(ptrLayout);
Layout=&l;
}
 
void variant::setPtrLayout(layout* l){
setType(ptrLayout);
Layout=l;
}

#ifdef SCHEMATIC
void variant::setSchematic(schematic l){
setType(ptrSchematic);
Schematic=&l;
}

void variant::setPtrSchematic(schematic* l){
setType(ptrSchematic);
Schematic=l;
}

void variant::setPtrSchematicDisplay(schematicDisplay* l){
setType(ptrSchematicDisplay);
SchematicDisplay=l;
}

void variant::setSchematicDisplay(schematicDisplay l){
setType(ptrSchematicDisplay);
SchematicDisplay=&l;
}


void variant::setPtrSheetList(sheetList* l){
setType(ptrSheetList);
SheetList=l;
}

void variant::setSheetList(sheetList l){
setType(ptrSheetList);
SheetList=&l;
}


void variant::setPtrSheet(sheet* l){
setType(ptrSheet);
Sheet=l;
}

void variant::setSheet(sheet l){
setType(ptrSheet);
Sheet=&l;
}


void variant::setPtrSElement(sElement* l){
setType(ptrSElement);
SElement=l;
}

void variant::setSElement(sElement l){
setType(ptrSElement);
SElement=&l;
}


void variant::setPtrSElementList(sElementList *l){
  setType(ptrSElementList);
  SElementlist=l;
}

void variant::setSElementList(sElementList l){
  setType(varSElementList);
  *SElementlist=l;
}

sElementList* variant::getSElementList()const{
   if ((type==ptrSElementList)||(type==varSElementList)||(type==ptrVoid)) return SElementlist;
 throw 21;
}

#endif

void variant::setPoint(QPoint p){
setType(varPoint);
*Point=p;
}
void variant::setPointArray(pointArray l){
setType(varPointArray);
*PointArray=l;
}
void variant::setCell(cell c){
setType(varCell);
*Cell=c;
}
void variant::setCellList(cellList l){
setType(varCellList);
*CellList=l;
}
void variant::setElement(element l){
setType(varElement);
*Element=l;
}
void variant::setElementList(elementList l){
setType(varElementList);
*ElementList=l;
}
void variant::setPtrPoint(QPoint *p){
setType(ptrPoint);
Point=p;
}
void variant::setPtrPointArray(pointArray *l){
setType(ptrPointArray);
PointArray=l;
}
void variant::setPtrCell(cell *c){
//printf("before set%d:%d\n",c,Cell);
setType(ptrCell);
Cell=c;
//printf("after set %d:%d\n",c,Cell);
}
void variant::setPtrCellList(cellList *l){
setType(ptrCellList);
CellList=l;
}
void variant::setPtrElement(element *l){
setType(ptrElement);
Element=l;
}
void variant::setPtrElementList(elementList *l){
setType(ptrElementList);
ElementList=l;
}

file variant::getFile() const{
 if ((type==ptrFile)||(type==varFile)||(type==ptrVoid)) return *File;
 throw 21;
}

file* variant::getPtrFile() const{
 if ((type==ptrFile)||(type==varFile)||(type==ptrVoid)) return File;
 throw 21;
}

void variant::setFile(file fi){
setType(varFile);
*File=fi;
}

void variant::setPtrFile(file *fi){
setType(ptrFile);
File=fi;
}

layerTranslator variant::getLayerTranslator() const{
	 if ((type==ptrLayerTranslator)||(type==varLayerTranslator)||(type==ptrVoid)) return *LayerTranslator;
 throw 21;
}
layerTranslator* variant::getPtrLayerTranslator() const{
	 if ((type==ptrLayerTranslator)||(type==varLayerTranslator)||(type==ptrVoid)) return LayerTranslator;
 throw 21;
}
void variant::setLayerTranslator(layerTranslator i){
	setType(varLayerTranslator);
*LayerTranslator=i;
}
void variant::setPtrLayerTranslator(layerTranslator *i){
	setType(varLayerTranslator);
LayerTranslator=i;
}


void variant::setType(varType t){
  deleteData();
  data=NULL;
  type=t;
  switch(t){
  case varInt16:
  case varInt32:
  case varInt:
  	i=&int_;
	deleteAfter=false;
	break;
  case varVoid:
  	data=NULL;
	deleteAfter=false;
	break;
  case varBool:
	b=&bool_;
	deleteAfter=false;
	break;
  case varDouble:
  	d=&double_;
	deleteAfter=false;
	break;
  case varString:
  	s=new QString();
	(*s)="";
	deleteAfter=true;
	break;
  case varStringList:
  	sl=new QStringList();
	sl->clear();
	deleteAfter=true;
	break;
  case ptrString:
  case ptrStringList:
  case ptrDouble:
  case ptrBool:
  case ptrInt:	
  case ptrLayout:
#ifdef SCHEMATIC
	case ptrSchematic:
	case ptrSchematicDisplay:
	case ptrSheetList:
	case ptrSheet:
	case ptrSElement:
	case ptrSElementList:
#endif
#ifdef TEXTEDIT
	case ptrTextEdit:
	case ptrTextDisplay:
#endif
  case ptrCellList:
  case ptrDrawingField:
  case ptrCell:
  case ptrVoid:
  case ptrElement:
  case ptrElementList:
  case ptrPoint:
  case ptrPointArray:
  case ptrRect:
  case ptrFile:
  case ptrDrc:
#ifdef netlistutility
  case ptrNetListModule:
  case ptrNetList:
  case ptrNetListDevice:
#endif
#ifdef barcodeutility
  case ptrBarcodeModule:
#endif
#ifdef backgroundutility
  case ptrBackgroundModule:
#endif
#ifdef USE_3d
  case ptrView3dModule:
#endif
  case ptrInt16:
  case ptrInt32:
  case ptrLayerTranslator:
  	data=NULL;
	deleteAfter=false;
	break;
  case varCell:
	deleteAfter=true;
	Cell = new cell();
	break;
  case varCellList:
	deleteAfter=true;
	CellList = new cellList();
	break;
  case varDrawingField:
	deleteAfter=true;
	DrawingField = new drawingField();
	break;
  case varRect:
	deleteAfter=true;
	Rect = new QRect();
	break;
  case varElement:
	deleteAfter=true;
	Element = new element();
	break;
  case varElementList:
	deleteAfter=true;
	ElementList = new elementList();
	break;
#ifdef SCHEMATIC
  case varSElementList:
	deleteAfter=true;
	SElementlist = new sElementList();
	break;
#endif
  case varPoint:
	deleteAfter=true;
	Point = new QPoint();
	break;
  case varPointArray:
	deleteAfter=true;
	PointArray = new pointArray();
	break;
  case varFile:
	deleteAfter=true;
	File = new file();
	break;
  case varDrc:
	deleteAfter=true;
	Drc = new drc();
	break;
  case varLayerTranslator:
	deleteAfter=true;
	LayerTranslator = new layerTranslator();
	break;
#ifdef netlistutility
  case varNetList:
	deleteAfter=true;
	NetList = new netList();
	break;
  case varNetListDevice:
	deleteAfter=true;
	NetListDevice = new netListDevice();
	break;
#endif
  }
}


variant & variant::operator=(const variant &t){
   //printf("=%d\n",t.data);
   setType(t.type);
   switch (type){
   case varInt16:
   case varInt32:
	   setType(varInt);
   case varInt:
   	*i= t.getInt();
	break;
   case varBool:
	*b=t.getBool();
	break;
   case varDouble:
  	*d=t.getDouble();
	break;
   case varString:
        *s=t.getString();
   	break;
   case varStringList:
        *sl=t.getStringList();
   	break;
   case varCell:
  	*Cell=(*(t.getCell()));
	break;
   case varCellList:
  	*CellList=(*(t.getCellList()));
	break;
   case varDrawingField:
   	throw 20;
       	//*DrawingField = (t.getDrawingField()->copy());
	break;
   case varRect:
	*Rect=(*(t.getRect()));
	break;
   case varElement:
	*Element=(*(t.getElement()));
	break;
   case varElementList:
	*ElementList=(*(t.getElementList()));
	break;
#ifdef SCHEMATIC
   case varSElementList:
	*SElementlist=(*(t.getSElementList()));
	break;
#endif
   case varPoint:
	*Point=(*(t.getPoint()));
	break;
   case varPointArray:
	*PointArray=(*(t.getPointArray()));
	break;
   case varFile:
	*File=t.getFile();
	break;
   case varLayerTranslator:
	*LayerTranslator=t.getLayerTranslator();
	break;
#ifdef netlistutility
   case varNetList:
	*NetList= (*(t.getNetList()));
	break;
   case varNetListDevice:
	*NetListDevice=(*(t.getNetListDevice()));
	break;
#endif
   case varDrc:
	throw 20;
	//*Drc=(*t.getDrc());
	break;
   default: //all Pointer
   	data=t.data;
   	
   }
  return *this;
}

variant & variant::operator<<(const variant &t){
   if (t.type== varVoid)
    throw 20;

   switch (type){
    case varInt16:
	  *int16=t.getInt();
	break;
   case varInt32:
	  *int32=t.getInt();
	break;
   case varInt:
   	*i= t.getInt();
	break;
   case varBool:
	*b=t.getBool();
	break;
   case varDouble:
  	*d=t.getDouble();
	break;
   case varString:
	//printf("%s ->%s\n",s->toAscii().data(),t.getString().toAscii().data());
        *s=t.getString();
   	break;
   case varStringList:
	//printf("%s ->%s\n",s->toAscii().data(),t.getString().toAscii().data());
        *sl=t.getStringList();
   	break;
   case varCell:
  	*Cell= *t.getCell();
	break;
   case varCellList:
  	*CellList= *t.getCellList();
	break;
   case varDrawingField:
   	throw 20;
       	//*DrawingField = *t.getDrawingField();
	break;
   case varRect:
	*Rect=(*(t.getRect()));
	break;
   case varElement:
	*Element=(*(t.getElement()));
	break;
   case varElementList:
	*ElementList=(*(t.getElementList()));
	break;
#ifdef SCHEMATIC
   case varSElementList:
	*SElementlist=(*(t.getSElementList()));
	break;
#endif
   case varPoint:
	*Point=(*(t.getPoint()));
	break;
   case varPointArray:
	*PointArray=(*(t.getPointArray()));
	break;
   case varFile:
	*File=t.getFile();
	break;
   case varLayerTranslator:
	*LayerTranslator=t.getLayerTranslator();
	break;
#ifdef netlistutility
   case varNetList:
	*NetList= (*(t.getNetList()));
	break;
   case varNetListDevice:
	*NetListDevice=(*(t.getNetListDevice()));
	break;
#endif
   case varDrc:
	throw 20;
	//*Drc=(*t.getDrc());
	break;
   default: //all Pointer
   	data=t.data;
	
   }
  return *this;
}

variant & variant::operator+=(const variant &t){
   switch (type){
   case varInt16:
	   *int16+=t.getInt();
	   break;
   case varInt32:
	   	*int32+=t.getInt();
	   break;
   case varInt:
   	*i +=t.getInt();
	break;
  /* case varBool:
	*b +=t.getBool();
	break;*/
   case varDouble:
  	*d+=t.getDouble();
	break;
   case varString:
	//printf(" %s + %s =",s->toAscii().data(),t.getString().toAscii().data());
        *s +=t.getString();
	//printf("\'%s\' \n",s->toAscii().data());
   	break;
   case varPoint:
   	*(Point) += *(t.getPoint());
	break;
   default:
   	throw 20;
   }
  return *this;
}
variant & variant::operator-=(const variant &t){
   switch (type){
    case varInt16:
	  *int16-=t.getInt();
	break;
    case varInt32:
	  *int32-=t.getInt();
	break;
   case varInt:
   	*i -=t.getInt();
	break;
 /*   case varBool:
	*b-=t.getBool();
	break;*/
   case varDouble:
  	*d-=t.getDouble();
	break;
   case varPoint:
   	*(Point) -= *(t.getPoint());
	break;
   default:
   	throw 20;
   }
  return *this;
}
variant & variant::operator*=(const variant &t){
   switch (type){
    case varInt16:
	  *int16*=t.getInt();
	break;
    case varInt32:
	  *int32*=t.getInt();
	break;
   case varInt:
   	(*i) *= t.getInt();
	break;
  /* case varBool:
	*b *= t.getBool();
	break;*/
   case varDouble:
  	*d *= t.getDouble();
	break;
   default:
   	throw 20;
   }
  return *this;
}
variant & variant::operator/=(const variant &t){
   switch (type){
    case varInt16:
	  *int16/=t.getInt();
	break;
    case varInt32:
	  *int32/=t.getInt();
	break;
   case varInt:
	if (t.getInt()==0) throw 31;
   	*i/= t.getInt();
	break;
 /*   case varBool:
	*b /= t.getBool();
	break;*/
   case varDouble:
	if (t.getDouble()==0) throw 31;
  	*d /= t.getDouble();
	break;
   default:
   	throw 20;
   }
  return *this;
}
variant & variant::operator++(int){
   switch (type){
    case varInt16:
	  (*int16)++;
	break;
    case varInt32:
	  (*int32)++;
	break;
   case varInt:
   	(*i)++;
	break;
   case varBool:
	(*b)=!(*b);
	break;
   case varDouble:
  	(*d)++;
	break;
   case varString:
   	break;
   default:
   	throw 20;
   }
  return *this;
}
variant & variant::operator--(int){
   switch (type){
    case varInt16:
	  (*int16)--;
	break;
    case varInt32:
	  (*int32)--;
	break;
   case varInt:
   	(*i)--;
	break;
   case varBool:
	(*b)=!(*b);
	break;
   case varDouble:
  	(*d)--;
	break;
   case varString:
   	break;
   default:
   	throw 20;
   	;
   }
  return *this;
}

const variant operator* (const variant &r1,const variant &r2){
 variant r;
 switch (r1.type){
    case varInt16:
	case varInt32:
	r.setType( varInt);
   	*(r.i) = r1.getInt()*r2.getInt();
	break;
   case varInt:
   	r.setType(r1.type);
   	*(r.i) = r1.getInt()*r2.getInt();
	break;
   case varDouble:
   	r.setType(r1.type);
   	*(r.d) = r1.getDouble()*r2.getDouble();
	break;
   case varBool:
   	r.setType(r1.type);
   	*(r.b) = r1.getBool() && r2.getBool();
	break;
   case varString:
   	r.setType(r1.type);
   	*(r.s) = r1.getString();
	break;
   default:
   	throw 20;
   }
  return r;
}

const variant operator! (const variant &r1){
 variant r;
 switch (r1.type){
   case varBool:
   	r.setType(r1.type);
   	*(r.b) = !r1.getBool();
	break;
   default:
   	throw 20;
   }
  return r;
}

const variant operator/ (const variant &r1,const variant &r2){
 variant r;
 switch (r1.type){
    case varInt16:
	case varInt32:
	r.setType( varInt);
   	*(r.i) = r1.getInt()/r2.getInt();
	break;
   case varInt:
   	r.setType(r1.type);
	if (r2.getInt()==0) throw 31;
   	*(r.i) = r1.getInt()/r2.getInt();
	break;
     case varDouble:
   	r.setType(r1.type);
	if (r2.getDouble()==0) throw 31;
   	*(r.d) = r1.getDouble()/r2.getDouble();
	break;
   case varBool:
   	r.setType(r1.type);
   	*(r.b) = r1.getBool() && r2.getBool();
	break;
   case varString:
   	r.setType(r1.type);
   	*(r.s) = r1.getString();
	break;
   default:
   	throw 20;
   }
  return r;
}

const variant operator+ (const variant &r1,const variant &r2){
 variant r;
 switch (r1.type){
    case varInt16:
	case varInt32:
	r.setType( varInt);
   	*(r.i) = r1.getInt()+r2.getInt();
	break;
   case varInt:
   	r.setType(r1.type);
   	*(r.i) = r1.getInt()+r2.getInt();
	break;
   case varDouble:
   	r.setType(r1.type);
   	*(r.d) = r1.getDouble()+r2.getDouble();
	break;
   case varBool:
   	r.setType(r1.type);
   	*(r.b) = r1.getBool() + r2.getBool();
	break;
   case varString:
   	r.setType(r1.type);
   	*(r.s) = r1.getString() + r2.getString();
	break;
   case varPoint:
   	r.setType(r1.type);
   	*(r.Point) = *(r1.getPoint()) + *(r2.getPoint());
	break;
   default:
   	throw 20;
   }
  return r;
}
const variant operator- (const variant &r1,const variant &r2){
 variant r;
 switch (r1.type){
    case varInt16:
	case varInt32:
	r.setType( varInt);
   	*(r.i) = r1.getInt()-r2.getInt();
	break;
   case varInt:
   	r.setType(r1.type);
   	*(r.i) = r1.getInt()-r2.getInt();
	break;
   case varDouble:
   	r.setType(r1.type);
   	*(r.d) = r1.getDouble()-r2.getDouble();
	break;
   case varBool:
   	r.setType(r1.type);
   	*(r.b) = r1.getBool() - r2.getBool();
	break;
   case varString:
   	r.setType(r1.type);
   	*(r.s) = r1.getString() ;
	break;
   case varPoint:
   	r.setType(r1.type);
   	*(r.Point) = *(r1.getPoint()) - *(r2.getPoint());
	break;
   default:
   	throw 20;
   }
  return r;
}


const variant operator== (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt()==r2.getInt());
	break;
      case varDouble:
   	*(r.b) = (r1.getDouble()==r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() == r2.getBool());
	break;
   case varString:
   	*(r.b) = (r1.getString()==r2.getString()) ;
	break;
   case varCell:
  	throw 20; //*(r.b) = (*(r1.getCell())== (*(r2.getCell())));
	break;
   case varCellList:
  	throw 20; //*(r.b)=(*r1.getCellList()==(*r2.getCellList()));
	break;
   case varDrawingField:
       	throw 20; //*(r.b)= (*r1.getDrawingField() ==(* r2.getDrawingField()));
	break;
   case varRect:
	*(r.b)=(*r1.getRect()==(*r2.getRect()));
	break;
   case varElement:
	throw 20; //*(r.b)=(*r1.getElement()==(*r2.getElement()));
	break;
   case varElementList:
	throw 20; //*(r.b)=(*r1.getElementList()==(*r2.getElementList()));
#ifdef SCHEMATIC
   case varSElementList:
	throw 20;
	break;
#endif
	break;
   case varPoint:
	*(r.b)=(*r1.getPoint()==(*r2.getPoint()));
	break;
   case varPointArray:
	*(r.b)=(*r1.getPointArray()==(*r2.getPointArray()));
	break;
   case varLayerTranslator:
	throw 20; //*(r.b)=(*r1.getLayerTranslator()==(*r2.getLayerTranslator()));
	break;
   case varFile:
	*(r.b)=false;
	break;
   default: //all pointer
   	*(r.b)=(r1.data == r2.data);
   }
  return r;
}
const variant operator!= (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt()!=r2.getInt());
	break;
   case varDouble:
   	*(r.b) = (r1.getDouble()!=r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() != r2.getBool());
	break;
   case varString:
   	*(r.b) = (r1.getString()!=r2.getString()) ;
	break;
   case varCell:
  	throw 20; //*(r.b)=(*r1.getCell()!= *r2.getCell());
	break;
   case varCellList:
  	throw 20; //*(r.b)=(*r1.getCellList()!= *r2.getCellList());
	break;
   case varDrawingField:
       	throw 20; //*(r.b)=(*r1.getDrawingField()!= *r2.getDrawingField());
	break;
   case varRect:
	*(r.b)=(*r1.getRect()!= *r2.getRect());
	break;
   case varElement:
	throw 20; //*(r.b)=(*r1.getElement()!= *r2.getElement());
	break;
   case varElementList:
	throw 20; //*(r.b)=(*r1.getElementList()!= *r2.getElementList());
	break;
#ifdef SCHEMATIC
   case varSElementList:
	throw 20;
	break;
#endif
   case varPoint:
	*(r.b)=(*r1.getPoint()!= *r2.getPoint());
	break;
   case varPointArray:
	*(r.b)=(*r1.getPointArray()!= *r2.getPointArray());
	break;
   case varLayerTranslator:
	throw 20; //*(r.b)=(*r1.getLayerTranslator()==(*r2.getLayerTranslator()));
	break;
   case varFile:
	*(r.b)=true;
	break;
   default: //all pointer
   	*(r.b)=(r1.data != r2.data);
   }
  return r;
}
const variant operator<= (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt() <= r2.getInt());
	break;
      case varDouble:
   	*(r.b) = (r1.getDouble() <= r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() <= r2.getBool());
	break;
   case varString:
   	*(r.b) = (r1.getString() <= r2.getString()) ;
	break;
   default:
   	throw 20;
   }
  return r;
}
const variant operator>= (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt() >= r2.getInt());
	break;
      case varDouble:
   	*(r.b) = (r1.getDouble() >= r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() >= r2.getBool());
	break;
   case varString:
   	*(r.b) = (r1.getString() >= r2.getString()) ;
	break;
   default:
   	throw 20;
   }
  return r;
}
const variant operator< (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt() < r2.getInt());
	break;
      case varDouble:
   	*(r.b) = (r1.getDouble() < r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() < r2.getBool());
	break;
   case varString:
   	*(r.b) = (r1.getString() < r2.getString()) ;
	break;
   default:
   	throw 20;
   }
  return r;
}
const variant operator> (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt() > r2.getInt());
	break;
      case varDouble:
   	*(r.b) = (r1.getDouble() > r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() > r2.getBool());
	break;
   case varString:
   	*(r.b) = (r1.getString() > r2.getString()) ;
	break;
   default:
   	throw 20;
   }
  return r;
}
const variant operator&& (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt() && r2.getInt());
	break;
      case varDouble:
   	*(r.b) = (r1.getDouble() && r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() && r2.getBool());
	break;
  /* case varString:
   	*(r.b) = (r1.getString() && r2.getString()) ;
	break;*/
   default:
   	throw 20;
   }
  return r;
}

const variant operator|| (const variant &r1,const variant &r2){
 variant r;
 r.setType(varBool);
 switch (r1.type){
   case varInt:
   case varInt16:
   case varInt32:
   	*(r.b) = (r1.getInt()||r2.getInt());
	break;
   case varDouble:
   	*(r.b) = (r1.getDouble()||r2.getDouble());
	break;
   case varBool:
   	*(r.b) = (r1.getBool() || r2.getBool());
	break;
 /*  case varString:
   	*(r.b) = (r1.getString()||r2.getString()) ;
	break;*/
   default:
   	throw 20;
  
   }
  return r;
}

void variant::setClassHandler(keywords *k){
  switch (type){
   case varVoid:
   case varInt:	
   case varInt16:
   case varInt32:
   case varBool:
   case varDouble:
   case ptrDouble:
   case ptrBool:
   case ptrInt:	
   case ptrInt16:
   case ptrInt32:
   case ptrVoid:
   	k->type=var;
	k->classHandler=NULL;
   	break;
   case ptrLayout:
   	k->type=intClass;
	k->classHandler=&macro::layoutHandler_classHandler;
	break;
   case varCell:
   case ptrCell:
  	k->type=intClass;
	k->classHandler=&macro::cellHandler_classHandler;
	break;
   case varCellList:
   case ptrCellList:
  	k->type=intClass;
	k->classHandler=&macro::cellListHandler_classHandler;
	break;
   case varDrawingField:
   case ptrDrawingField:
       	k->type=intClass;
	k->classHandler=&macro::drawingFieldHandler_classHandler;
	break;
   case varRect:
   case ptrRect:
	k->type=intClass;
	k->classHandler=&macro::rectHandler_classHandler;
	break;
   case varElement:
   case ptrElement:
	k->type=intClass;
	k->classHandler=&macro::elementHandler_classHandler;
	break;
   case varElementList:
   case ptrElementList:
	k->type=intClass;
	k->classHandler=&macro::elementListHandler_classHandler;
	break;
#ifdef SCHEMATIC
   case varSElementList:
   case ptrSElementList:
	k->type=intClass;
	k->classHandler=&macro::sElementListHandler_classHandler;
	break;
#endif
   case varPoint:
   case ptrPoint:
	k->type=intClass;
	k->classHandler=&macro::pointHandler_classHandler;
	break;
   case varPointArray:
   case ptrPointArray:
	k->type=intClass;
	k->classHandler=&macro::pointArrayHandler_classHandler;
	break;
   case varString:
   case ptrString:
        k->type=intClass;
	k->classHandler=&macro::stringHandler_classHandler;
	break;
   case varStringList:
   case ptrStringList:
        k->type=intClass;
	k->classHandler=&macro::stringListHandler_classHandler;
	break;
   case varFile:
   case ptrFile:
        k->type=intClass;
	k->classHandler=&macro::fileHandler_classHandler;
	break;
   case varDrc:
   case ptrDrc:
        k->type=intClass;
	k->classHandler=&macro::drcHandler_classHandler;
	break;
#ifdef netlistutility
	case ptrNetListModule:
    	k->type=intClass;
	k->classHandler=&macro::netListModuleHandler_classHandler;
	break;
	case varNetList:
	case ptrNetList:
    	k->type=intClass;
	k->classHandler=&macro::netListHandler_classHandler;
	break;
	case varNetListDevice:
	case ptrNetListDevice:
    	k->type=intClass;
	k->classHandler=&macro::netListDeviceHandler_classHandler;
	break;
#endif
#ifdef barcodeutility
	case ptrBarcodeModule:
        k->type=intClass;
	k->classHandler=&macro::barcodeModuleHandler_classHandler;
	break;
#endif
#ifdef backgroundutility
	case ptrBackgroundModule:
        k->type=intClass;
	k->classHandler=&macro::backgroundModuleHandler_classHandler;
	break;
#endif
#ifdef USE_3d
	case ptrView3dModule:
    	k->type=intClass;
	k->classHandler=&macro::view3dModuleHandler_classHandler;
	break;
#endif
#ifdef SCHEMATIC
	case ptrSchematic:
    	k->type=intClass;
	k->classHandler=&macro::schematicHandler_classHandler;
	break;
	case ptrSchematicDisplay:
    	k->type=intClass;
	k->classHandler=&macro::schematicDisplayHandler_classHandler;
	break;
	case ptrSheet:
    	k->type=intClass;
	k->classHandler=&macro::sheetHandler_classHandler;
	break;
	case ptrSheetList:
    	k->type=intClass;
	k->classHandler=&macro::sheetListHandler_classHandler;
	break;
	case ptrSElement:
    	k->type=intClass;
	k->classHandler=&macro::sElementHandler_classHandler;
	break;
#endif
#ifdef TEXTEDIT
	case ptrTextEdit:
	k->type=intClass;
	k->classHandler=&macro::textEditHandler_classHandler;
	break;
	case ptrTextDisplay:
	k->type=intClass;
	k->classHandler=&macro::textDisplayHandler_classHandler;
	break;
#endif
   case varLayerTranslator:
   case ptrLayerTranslator:
        k->type=intClass;
	k->classHandler=&macro::layerTranslatorHandler_classHandler;
	break;
   default:
   	;
   }
}
variant variant::convertToPtr()const{
variant r;
r.data=data;
r.deleteAfter=false;
 switch (type){
   case varVoid: r.type=ptrVoid; break;
   case varInt:	r.type=ptrInt; break;
   case varInt16: r.type=ptrInt16; break;
   case varInt32: r.type=ptrInt32; break;
   case varBool: r.type=ptrBool; break;
   case varDouble: r.type=ptrDouble; break;
   case varString: r.type=ptrString; break;
   case varStringList: r.type=ptrStringList; break;
   case varCell: r.type=ptrCell; break;
   case varCellList: r.type=ptrCellList; break;
   case varDrawingField: r.type=ptrDrawingField; break;
   case varRect: r.type=ptrRect; break;
   case varElement: r.type=ptrElement; break;
   case varElementList: r.type=ptrElementList; break;
   case varPoint: r.type=ptrPoint; break;
   case varPointArray: r.type=ptrPointArray; break;
   case varFile: r.type=ptrFile; break;
   case varLayerTranslator: r.type=ptrLayerTranslator; break;
   case varDrc: r.type=ptrDrc; break;
#ifdef netlistutility
   case varNetList: r.type=ptrNetList; break;
   case varNetListDevice: r.type=ptrNetListDevice; break;
#endif
#ifdef SCHEMATIC
   case varSElementList: r.type=ptrSElementList; break;
#endif
   default:
   	throw 27;
   }
  return r;
}
variant variant::convertToVar()const{
variant r;
r.data=data;
r.deleteAfter=false;
 switch (type){
   case ptrString: r.type=varString; break;
   case ptrStringList: r.type=varStringList; break;
   case ptrDouble: r.type=varDouble; break;
   case ptrBool: r.type=varBool; break;
   case ptrInt:	r.type=varInt; break;
   case ptrVoid: r.type=varVoid; break;
   //case ptrLayout: r.type=varLayout; break;
   case ptrCell: r.type=varCell; break;
   case ptrCellList: r.type=varCellList; break;
   case ptrDrawingField: r.type=varDrawingField; break;
   case ptrRect: r.type=varRect; break;
   case ptrElement: r.type=varElement; break;
   case ptrElementList: r.type=varElementList; break;
   case ptrPoint: r.type=varPoint; break;
   case ptrPointArray: r.type=varPointArray; break;
   case ptrFile: r.type=varFile; break;
   case ptrDrc: r.type=varDrc; break;
   case ptrLayerTranslator: r.type=varLayerTranslator; break;
#ifdef netlistutility
   case ptrNetList: r.type=varNetList; break;
   case ptrNetListDevice: r.type=varNetListDevice; break;
#endif
#ifdef SCHEMATIC
   case ptrSElementList: r.type=varSElementList; break;
#endif
   default:
   	throw 28;
   }
 return r;
}

const variant operator% (const variant &r1,const variant &r2){
 variant r;
 switch (r1.type){
   case varInt16:
   case varInt32:
	r.setType( varInt);
   	*(r.i) = r1.getInt()%r2.getInt();
	break;
   case varInt:
   	r.setType(r1.type);
   	*(r.i) = r1.getInt()%r2.getInt();
	break;
   default:
   	throw 20;
   }
  return r;
}
