AnimationForm::AnimationForm(CEditData *pImageData, CSettings *pSetting, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::AnimationForm)
{
	m_pEditData		= pImageData ;
	m_pSetting		= pSetting ;
	m_bDontSetData	= false ;
	m_frameStart	= pSetting->getFrameStart() ;
	m_frameEnd		= pSetting->getFrameEnd() ;

	m_oldWinSize = QSize(-1, -1) ;

	ui->setupUi(this);

	m_pEditData->setTreeView(ui->treeView) ;

	ui->label_frame->setEditData(m_pEditData) ;
	ui->label_frame->setHorizontalBar(ui->horizontalScrollBar_frame) ;
	m_pDataMarker = ui->label_frame ;

	setFocusPolicy(Qt::StrongFocus);

	m_pGlWidget = new AnimeGLWidget(pImageData, pSetting, this) ;
	ui->scrollArea_anime->setWidget(m_pGlWidget);
	m_pGlWidget->resize(m_pSetting->getAnmWindowW(), m_pSetting->getAnmWindowH());
	m_pGlWidget->setDrawArea(m_pSetting->getAnmWindowW(), m_pSetting->getAnmWindowH());
	m_pGlWidget->show();

	ui->radioButton_pos->setChecked(true);
	ui->checkBox_grid->setChecked(true);
	ui->spinBox_fps->setValue(60) ;
	ui->checkBox_frame->setChecked(pSetting->getDrawFrame());
	ui->checkBox_center->setChecked(pSetting->getDrawCenter());
	ui->spinBox_frame_start->setValue(m_frameStart) ;
	ui->spinBox_frame_end->setValue(m_frameEnd) ;
	ui->label_frame->slot_setFrameStart(m_frameStart) ;
	ui->label_frame->slot_setFrameEnd(m_frameEnd) ;

	for ( int i = 0 ; i < m_pEditData->getImageDataListSize() ; i ++ ) {
		CEditData::ImageData *p = m_pEditData->getImageData(i) ;
		if ( !p ) { continue ; }
		ui->comboBox_image_no->addItem(tr("%1").arg(p->nNo));
	}

	m_pSplitter = new AnimationWindowSplitter(this) ;
	m_pSplitter->addWidget(ui->treeView) ;
	m_pSplitter->addWidget(ui->scrollArea_anime) ;
	m_pSplitter->setGeometry(ui->treeView->pos().x(),
						   ui->treeView->pos().y(),
						   ui->scrollArea_anime->width()+ui->scrollArea_anime->pos().x()-ui->treeView->pos().x(),
						   ui->treeView->height());

	{
		CObjectModel *pModel = m_pEditData->getObjectModel() ;

		ui->treeView->setModel(pModel);
		ui->treeView->header()->setHidden(true);
		ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);

		ui->treeView->setDragEnabled(true) ;
		ui->treeView->setAcceptDrops(true) ;
		ui->treeView->setDropIndicatorShown(true) ;
		ui->treeView->setDragDropMode(QAbstractItemView::DragDrop) ;
		ui->treeView->setFocusPolicy(Qt::NoFocus);

		ObjectItem *root = pModel->getItemFromIndex(QModelIndex()) ;
		if ( !root->childCount() ) {
			addNewObject(trUtf8("New Object"));
		}
		else {
			if ( root->child(0) ) {
				QModelIndex index = pModel->index(0) ;
				ui->treeView->setCurrentIndex(index);
			}
		}
	}

	m_pActTreeViewAdd		= new QAction(QString("Add Object"), this);
	m_pActTreeViewCopy		= new QAction(QString("Copy Object"), this) ;
	m_pActTreeViewDel		= new QAction(QString("Delete"), this);
	m_pActTreeViewLayerDisp = new QAction(QString("Disp"), this) ;
	m_pActTreeViewLayerLock = new QAction(QString("Lock"), this) ;

	m_pTimer = new QTimer(this) ;
	m_pTimer->setInterval((int)(100.0f/6.0f));

	connect(ui->label_frame, SIGNAL(sig_changeValue(int)), this, SLOT(slot_frameChanged(int))) ;
	connect(ui->radioButton_pos, SIGNAL(clicked(bool)), this, SLOT(slot_clickedRadioPos(bool))) ;
	connect(ui->radioButton_rot, SIGNAL(clicked(bool)), this, SLOT(slot_clickedRadioRot(bool))) ;
	connect(ui->radioButton_center, SIGNAL(clicked(bool)), this, SLOT(slot_clickedRadioCenter(bool))) ;
	connect(ui->radioButton_scale, SIGNAL(clicked(bool)), this, SLOT(slot_clickedRadioScale(bool))) ;
	connect(ui->radioButton_path, SIGNAL(clicked(bool)), this, SLOT(slot_clickedRadioPath(bool))) ;

	connect(ui->treeView, SIGNAL(customContextMenuRequested(QPoint)),	this, SLOT(slot_treeViewMenuReq(QPoint))) ;
	connect(ui->treeView, SIGNAL(clicked(QModelIndex)),					this, SLOT(slot_changeSelectObject(QModelIndex))) ;

	connect(m_pGlWidget, SIGNAL(sig_dropedImage(QRectF, QPoint, int)), this, SLOT(slot_dropedImage(QRectF, QPoint, int))) ;
	connect(m_pGlWidget, SIGNAL(sig_selectLayerChanged(QModelIndex)), this, SLOT(slot_selectLayerChanged(QModelIndex))) ;
	connect(m_pGlWidget, SIGNAL(sig_dragedImage(FrameData)), this, SLOT(slot_setUI(FrameData))) ;
	connect(m_pGlWidget, SIGNAL(sig_deleteFrameData()), this, SLOT(slot_deleteFrameData())) ;
	connect(m_pGlWidget, SIGNAL(sig_selectPrevLayer(QModelIndex, int, FrameData)), this, SLOT(slot_addNewFrameData(QModelIndex, int, FrameData))) ;
	connect(m_pGlWidget, SIGNAL(sig_frameDataMoveEnd(FrameData)), this, SLOT(slot_frameDataMoveEnd(FrameData))) ;
	connect(m_pGlWidget, SIGNAL(sig_dragedImage(FrameData)), this, SLOT(slot_portDragedImage(FrameData))) ;

	connect(ui->doubleSpinBox_pos_x,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changePosX(double))) ;
	connect(ui->doubleSpinBox_pos_y,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changePosY(double))) ;
	connect(ui->doubleSpinBox_pos_z,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changePosZ(double))) ;
	connect(ui->doubleSpinBox_rot_x,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeRotX(double))) ;
	connect(ui->doubleSpinBox_rot_y,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeRotY(double))) ;
	connect(ui->doubleSpinBox_rot_z,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeRotZ(double))) ;
	connect(ui->doubleSpinBox_scale_x,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeScaleX(double))) ;
	connect(ui->doubleSpinBox_scale_y,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeScaleY(double))) ;
	connect(ui->doubleSpinBox_uv_left,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeUvLeft(double))) ;
	connect(ui->doubleSpinBox_uv_right,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeUvRight(double))) ;
	connect(ui->doubleSpinBox_uv_top,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeUvTop(double))) ;
	connect(ui->doubleSpinBox_uv_bottom,SIGNAL(valueChanged(double)),	this, SLOT(slot_changeUvBottom(double))) ;
	connect(ui->doubleSpinBox_center_x,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeCenterX(double))) ;
	connect(ui->doubleSpinBox_center_y,	SIGNAL(valueChanged(double)),	this, SLOT(slot_changeCenterY(double))) ;
	connect(ui->spinBox_frame_start,	SIGNAL(valueChanged(int)),		this, SLOT(slot_changeFrameStart(int))) ;
	connect(ui->spinBox_frame_end,		SIGNAL(valueChanged(int)),		this, SLOT(slot_changeFrameEnd(int))) ;

	connect(m_pActTreeViewAdd,			SIGNAL(triggered()),			this, SLOT(slot_createNewObject())) ;
	connect(m_pActTreeViewCopy,			SIGNAL(triggered()),			this, SLOT(slot_copyObject())) ;
	connect(m_pActTreeViewDel,			SIGNAL(triggered()),			this, SLOT(slot_deleteObject())) ;
	connect(m_pActTreeViewLayerDisp,	SIGNAL(triggered()),			this, SLOT(slot_changeLayerDisp())) ;
	connect(m_pActTreeViewLayerLock,	SIGNAL(triggered()),			this, SLOT(slot_changeLayerLock())) ;

	connect(ui->pushButton_play,		SIGNAL(clicked()),				this, SLOT(slot_playAnimation())) ;
	connect(ui->pushButton_stop,		SIGNAL(clicked()),				this, SLOT(slot_stopAnimation())) ;
	connect(ui->pushButton_backward,	SIGNAL(clicked()),				this, SLOT(slot_backwardFrameData())) ;
	connect(ui->pushButton_forward,		SIGNAL(clicked()),				this, SLOT(slot_forwardFrameData())) ;
	connect(ui->checkBox_grid,			SIGNAL(clicked(bool)),			m_pGlWidget, SLOT(slot_setDrawGrid(bool))) ;
	connect(ui->checkBox_uv_anime,		SIGNAL(clicked(bool)),			this, SLOT(slot_changeUVAnime(bool))) ;
	connect(ui->spinBox_fps,			SIGNAL(valueChanged(int)),		this, SLOT(slot_changeAnimeSpeed(int))) ;
	connect(ui->comboBox_image_no,		SIGNAL(activated(QString)),		this, SLOT(slot_changeImageIndex(QString))) ;
	connect(m_pTimer,					SIGNAL(timeout()),				this, SLOT(slot_timerEvent())) ;
	connect(ui->spinBox_loop,			SIGNAL(valueChanged(int)),		this, SLOT(slot_changeLoop(int))) ;
	connect(ui->spinBox_r,				SIGNAL(valueChanged(int)),		this, SLOT(slot_changeColorR(int))) ;
	connect(ui->spinBox_g,				SIGNAL(valueChanged(int)),		this, SLOT(slot_changeColorG(int))) ;
	connect(ui->spinBox_b,				SIGNAL(valueChanged(int)),		this, SLOT(slot_changeColorB(int))) ;
	connect(ui->spinBox_a,				SIGNAL(valueChanged(int)),		this, SLOT(slot_changeColorA(int))) ;
	connect(ui->checkBox_frame,			SIGNAL(clicked(bool)),			this, SLOT(slot_changeDrawFrame(bool))) ;
	connect(ui->checkBox_center,		SIGNAL(clicked(bool)),			this, SLOT(slot_changeDrawCenter(bool))) ;
	connect(ui->checkBox_linear_filter,	SIGNAL(clicked(bool)),			this, SLOT(slot_changeLinearFilter(bool))) ;
	connect(ui->toolButton_picker,		SIGNAL(clicked()),				this, SLOT(slot_clickPicker())) ;
	connect(m_pSplitter,				SIGNAL(splitterMoved(int,int)), this, SLOT(slot_splitterMoved(int, int))) ;
	connect(m_pEditData->getObjectModel(), SIGNAL(sig_copyIndex(int,ObjectItem*,QModelIndex,Qt::DropAction)), this, SLOT(slot_copyIndex(int, ObjectItem*, QModelIndex,Qt::DropAction))) ;

	connect(ui->pushButton_del_path,	SIGNAL(clicked()),				this, SLOT(slot_delPath())) ;
	connect(this, SIGNAL(sig_changeFrameStart(int)),	ui->label_frame, SLOT(slot_setFrameStart(int))) ;
	connect(this, SIGNAL(sig_changeFrameEnd(int)),		ui->label_frame, SLOT(slot_setFrameEnd(int))) ;

	connect(ui->label_frame, SIGNAL(sig_changeValue(int)), ui->spinBox_nowSequence, SLOT(setValue(int))) ;
	connect(ui->spinBox_nowSequence, SIGNAL(valueChanged(int)), this, SLOT(slot_frameChanged(int))) ;
	connect(ui->horizontalScrollBar_frame, SIGNAL(valueChanged(int)), ui->label_frame, SLOT(slot_moveScrollBar(int))) ;
	connect(ui->label_frame, SIGNAL(sig_moveFrameData(int,int)), this, SLOT(slot_moveFrameData(int,int))) ;

	connect(m_pGlWidget, SIGNAL(sig_scrollWindow(QPoint)), this, SLOT(slot_scrollWindow(QPoint))) ;
}
void processLine(FILE * logf, struct SCRIPT * script, struct TYPING * types, 
				 unsigned long location, struct LINE * line){
	char * tokens = (char *) calloc(TOKENMAXNB*TOKENSIZE,sizeof(char));
	int nbtokens, i, j, index, storobj=-1, valobj=-1; int calldetected;
	
	//Detect system calls
	calldetected = monitorSytemCalls(logf,script,types,location,line);

	//Parse line
	nbtokens = decomposeLine(line->line,tokens,TOKENMAXNB,TOKENSIZE);
	
	for(i=0;i<nbtokens;i++){
		//Monitor string and processing and treat dependency			
		if(!strcasecmp(ACCESS(tokens,i),"Mid")
			||!strcasecmp(ACCESS(tokens,i),"Left")
			||!strcasecmp(ACCESS(tokens,i),"Ucase")
			||!strcasecmp(ACCESS(tokens,i),"Lcase")
			||!strcasecmp(ACCESS(tokens,i),"LTrim")
			||!strcasecmp(ACCESS(tokens,i),"RTrim")
			||!strcasecmp(ACCESS(tokens,i),"Replace")){
			int newstor = 0;
			int obj = isKnownObject(types,ACCESS(tokens,i+1));
			if(obj>-1 && i>=2 && ((char *)ACCESS(tokens,i-1))[0]=='='){
				int storobj = isKnownObject(types,ACCESS(tokens,i-2));
				if(storobj==-1){
					newstor = 1,
					storobj = addNewObject(types,NULL,getObjectNature(types,obj));
					addObjectReference(types,storobj,ACCESS(tokens,i-2));
					setObjectType(types,storobj,getObjectType(types,obj));
				}else{
					setObjectNature(types,storobj,getObjectNature(types,obj));
					setObjectType(types,storobj,getObjectType(types,obj));
				}
				if(newstor){strcpy_s(types->objects[storobj].ObjectName,
							NAME_MAX_LENGTH,types->objects[obj].ObjectName);}
				printLogEntry(logf, types, OP_AFF, storobj, obj);
			}
		}

		//Detect string proceclocal procedure and function calls
		index = isLocalProcedure(script,ACCESS(tokens,i));
		if(index>-1){
			//Avoid recursive calls
			//if((location&0xF0000000)==PROCLEVEL 
			//	&& index==(location&0x0FFFFFFF)){
			if(script->procedureslist[index].beingexecuted){
				printf("[+] Block recursive call to procedure %s\n",
						script->procedureslist[index].name);
			}else{
				script->procedureslist[index].beingexecuted = 1;
				//No return value, so can not be an affectation
				startProcedure(logf,script,types,index,line);
				script->procedureslist[index].beingexecuted = 0;
			}
			free(tokens); return;
		}else{
			index = isLocalFunction(script,ACCESS(tokens,i));
			if(index>-1){
				if(strcmp(ACCESS(tokens,i+1),"=")){//Avoid return values
					//Avoid recursive calls
					if(script->functionslist[index].beingexecuted){
						printf("[+] Block recursive call to function %s\n",
								script->functionslist[index].name);
					}else{
						script->functionslist[index].beingexecuted = 1;
						startFunction(logf,script,types,index,line);
						script->functionslist[index].beingexecuted = 0;
					}
					free(tokens); return;
				}else{
					line->type = AFFECTATION;
					updateReturnStorage(types, 
						script->functionslist[index].name, ACCESS(tokens,i+2));
					free(tokens); return;
				}//if call or return
			}
		}
	} if(calldetected) return;

	//Detect affectation of known object
	for(i=0;i<nbtokens;i++){
		if(((char *)ACCESS(tokens,i))[0]=='='||!strcasecmp(ACCESS(tokens,i),"in")){
			int maxobj = -1; int maxtype; int nullnat = 0;  int newstor = 0;
			int nbconselem; //Number of consecutive elements must
			int isarray = 0;//be < 2 except using & and array to concatenate
			
			//Either creation or retrieving of store object
			storobj = isKnownObject(types,ACCESS(tokens,i-1));
			if(storobj==-1){
				newstor = 1;
				storobj = addNewObject(types,NULL,0);
				addObjectReference(types,storobj,ACCESS(tokens,i-1));
			}//if unknown
			maxtype = getObjectType(types,storobj); 
			nbconselem = 0;

			//Look for significant passing value
			for(j=i+1;j<nbtokens;j++){
				if(!strcasecmp(ACCESS(tokens,j),"Array")){
					isarray = 1; j++;
				}//if
				if(((char *)ACCESS(tokens,j))[0]=='&'){
					nbconselem = 0;	
				}else{ 
					//Checks if access to a static attribute
					char stataccess[TOKENSIZE+5];
					strcpy_s(stataccess,5+TOKENSIZE,ACCESS(tokens,j));
					strcat_s(stataccess,5+TOKENSIZE,".");
					if(strcasestr(line->line,stataccess)){
						nbconselem = 0;
					}else{
						nbconselem++;
					}
				}//if
				if(!isarray && nbconselem>1) break;
				valobj = isKnownObject(types,ACCESS(tokens,j));
				if(valobj>-1){//known objects
					//Update store type when significant
					if(getObjectType(types,valobj)>maxtype){
						maxtype = getObjectType(types,valobj);
						maxobj = valobj;
					}
				}else if(ClassifyObject(ACCESS(tokens,j),&nullnat)>maxtype){//typed object
					maxobj = addNewObject(types,ACCESS(tokens,j),nullnat);
					maxtype = getObjectType(types,maxobj);
				}//if

			}//for
			if(maxobj>-1){
				line->type = AFFECTATION;
				setObjectType(types,storobj,getObjectType(types,maxobj));
				setObjectNature(types,storobj,getObjectNature(types,maxobj));
				if(newstor){strcpy_s(types->objects[storobj].ObjectName,
							NAME_MAX_LENGTH,types->objects[maxobj].ObjectName);}
				printLogEntry(logf, types, OP_AFF, storobj, maxobj);
			}
		}//if '=' found
	}//for
	free(tokens); 
}