#include "window.h"

using namespace std;
using namespace morpheo::tools::viewer::parser;
using namespace morpheo::tools::viewer::bdd;
using namespace morpheo::tools::viewer::graphics;

/*mouse press event handler*/
void Window::mousePressEvent (QMouseEvent *e){
  if(paint && (p.getArchitecture() != NULL)){

    compo = p.getComponent();
    
    QMouseEvent *mouseEvent = (QMouseEvent *) e;
    
    mouseX = mouseEvent->x();
    mouseY = mouseEvent->y();
    
    bool bc,b3 = false;
    int cx,cy,tx,ty;
    string s2,cc,nc,type,comm;
    bool found = false;

    /*search the component under the mouse focus*/
    for(QList<Component>::iterator it=compo->begin();it!=compo->end();++it){
      Coord *co = it->get_Position();
      int px = co->get_hg_x();
      int py = co->get_hg_y();
      int taillex = co->get_size_x();
      int tailley = co->get_size_y();
      QString t=QString::fromStdString(it->getType()).toLower();
      /*go to the next level if comoponent doubleclicked*/
      if(e->type() == QMouseEvent::MouseButtonDblClick && e->button() == Qt::LeftButton){
	
	if(mouseX >= px + MARGEX  && mouseY >= py +MARGEY && mouseX <= px+taillex + MARGEX  && mouseY <= py+tailley + MARGEY) {
	  
	  bc = false;
	  paint = false;
	  repaint();
          found=true;
	  this->setDisabled(true);
	}
      }
      if(found){  
       	mess = new QWidget();
	mess->setFixedSize(200,50);
	mess->move(200,50);
	QBoxLayout *b = new QBoxLayout(QBoxLayout::TopToBottom,0);
	QLabel *l = new QLabel();
	l->setText("please wait while charging");
	b->addWidget(l);
	mess->setLayout(b);
	mess->show();
	mess_open = true;

	p=base->get_BasePos(t.toStdString());
	entity = p.getEntity();
	c = new Coord(250,250,250,250);
	port_east = entity->getPortEast(c);
	port_west = entity->getPortWest(c);
	port_north = entity->getPortNorth(c);
	port_south = entity->getPortSouth(c);
	if(cpt_level!=0)
	  tab[cpt_level]=father;
	father = current;
	current = QString::fromStdString(t.toStdString());
	cpt_level++;
	tab[cpt_level] = father;
	paint = true;
	repaint();
     	erase_line(lt,ltype);
	erase_line(ln,lname);
	erase_comment();
	found = false;
	this->setDisabled(false);
	component_clicked = false;
      }
      /*search and display the informations of the component clicked*/
      if(e->type() == QMouseEvent::MouseButtonPress && e->button() == Qt::LeftButton){
	if(mouseX >= px + MARGEX  && mouseY >= py +MARGEY && mouseX <= px+taillex + MARGEX  && mouseY <= py+tailley + MARGEY) {
	  bc = true;
	  nc = it->getName();
	  cx = px;
	  cy = py;
	  tx = taillex;
	  ty = tailley;
	  type = it->getType();
	  BaseP tp = base->get_BasePos(t.toStdString());
	  if(&tp != NULL)
	    cc=tp.getComment();
	  component_clicked = true;
	}
	
	for(QList<Port>::iterator it=port_east.begin(); it!=port_east.end(); ++it){
	  portX = it->get_x();
	  portY = it->get_y();
	  if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 + MARGEY && mouseX <= portX + 15 +MARGEX && mouseY <= portY + 15 + MARGEY){
	    b3 = true;
	    s2 = it->getName();
	    comm = it->getComment();
	    type = it->getDirection();
	  }
	} 
   
	for(QList<Port>::iterator it=port_west.begin(); it!=port_west.end(); ++it){
	  portX = it->get_x() ;
	  portY = it->get_y() ;
	  if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 + MARGEY && mouseX <= portX + 15 + MARGEX && mouseY <= portY + 15 + MARGEY){
	    b3 = true;
	    s2 = it->getName();
	    comm = it->getComment();
	    type = it->getDirection();
	  }
	}
   
	for(QList<Port>::iterator it=port_north.begin(); it!=port_north.end(); ++it){
	  portX = it->get_x() ;
	  portY = it->get_y() ;
	  if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 +MARGEY && mouseX <= portX + 15 + MARGEX && mouseY <= portY + 15 +MARGEY){
	    b3 = true;
	    s2 = it->getName();
	    type = it->getDirection();
	    comm = it->getComment();
	  }
	}
   
	for(QList<Port>::iterator it=port_south.begin(); it!=port_south.end(); ++it){
	  portX = it->get_x() ;
	  portY = it->get_y() ;
	  if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 + MARGEY && mouseX <= portX + 15 +MARGEX && mouseY <= portY + 15 + MARGEY){
	    b3 = true;
	    s2 = it->getName();
	    comm = it->getComment();
	    type = it->getDirection();
	  }
	}
      }
    }
    if(bc){
      write_name("component",nc);
      write_type(type);
      write_comment(cc);
    }
    if(b3){
      write_name("signal",s2);
      write_type(type);
      write_comment(comm);
      component_clicked = true;
    }
  }
}

/*mouse move event handler*/
void Window::mouseMoveEvent(QMouseEvent *e){
  bool b  = false;
  bool b2 = false;
  bool b3 = false;
  int px,py,taillex,tailley,ppx,ppy;
  string s,s2,c,type;
  string comm;

   if(paint && !component_clicked){
     if(p.getArchitecture() != NULL){

       compo = p.getComponent();
       
       QMouseEvent *mouseEvent = (QMouseEvent *) e;
       
       mouseX = mouseEvent->x();
       mouseY = mouseEvent->y();
       
       /*display the component under the mouse focus*/
       for(QList<Component>::iterator it=compo->begin();it!=compo->end();++it){
	 Coord *co = it->get_Position();
	 px = co->get_hg_x();
	 py = co->get_hg_y();
	 taillex = co->get_size_x();
	 tailley = co->get_size_y();
	 QString t=QString::fromStdString(it->getType()).toLower();
	 QList<PortMap> *pm=it->getPortMap();
	 
	 if(e->type() == QMouseEvent::MouseMove){
	   if(mouseX >= px + MARGEX  && mouseY >= py +MARGEY && mouseX <= px+taillex + MARGEX  && mouseY <= py+tailley + MARGEY) {
	     b = true;
	     s = it->getName();
	     type = it->getType();
	     BaseP tp=base->get_BasePos(t.toStdString());
	     if(&tp!=NULL)
	       c=tp.getComment();
	     ppx = px;
	     ppy = py;
	     break;
	   }
	   else{
	     for (QList<PortMap>::iterator it3=pm->begin();it3!=pm->end();++it3) {
	       Signal *sig=base->getSignal(&p,it->getName(),new PortMap(*it3));
	       if(mouseX >= sig->get_src_x() - 15  + MARGEX  && mouseY >= sig->get_src_y() - 15 + MARGEY && mouseX <= sig->get_src_x() + 15  + MARGEX  && mouseY <= sig->get_src_y() + 15 +MARGEY){
		 b2 = true;
		 s = it3->getName();
		 break;
	       }
	     }
	   }   
	 }
       }
       
       if(b){
	 write_name("component",s);
	 write_type(type);
	 write_comment(c);
	 b3 = false;
	 b2 = false;
       }
     
       if(b2){
	 write_name("signal",s);
	 erase_line(lt,ltype);
	 erase_comment();
	 b3 = false;
	 b = false;
       }
     
       if(!b && !b2){
	 erase_line(lt,ltype);
	 erase_line(ln,lname);
	 erase_comment();
       }
     }
   
     p=base->get_BasePos(current.toStdString());
     Entity *ent = p.getEntity();
     Coord *c = new Coord(250,250,250,250);
     port_east = ent->getPortEast(c);
     port_west = ent->getPortWest(c);
     port_north = ent->getPortNorth(c);
     port_south = ent->getPortSouth(c);

     /*display the signal under the mouse focus*/
     for(QList<Port>::iterator it=port_east.begin(); it!=port_east.end(); ++it){
       portX = it->get_x();
       portY = it->get_y();
       if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 + MARGEY && mouseX <= portX + 15 +MARGEX && mouseY <= portY + 15 + MARGEY){
	 b3 = true;
	 s2 = it->getName();
	 comm = it->getComment();
	 type = it->getDirection();
       }
     } 
   
     for(QList<Port>::iterator it=port_west.begin(); it!=port_west.end(); ++it){
       portX = it->get_x() ;
       portY = it->get_y() ;
       if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 + MARGEY && mouseX <= portX + 15 + MARGEX && mouseY <= portY + 15 + MARGEY){
	 b3 = true;
	 s2 = it->getName();
	 comm = it->getComment();
	 type = it->getDirection();
       }
     }
   
     for(QList<Port>::iterator it=port_north.begin(); it!=port_north.end(); ++it){
       portX = it->get_x() ;
       portY = it->get_y() ;
       if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 +MARGEY && mouseX <= portX + 15 + MARGEX && mouseY <= portY + 15 +MARGEY){
	 b3 = true;
	 s2 = it->getName();
	 comm = it->getComment();
	 type = it->getDirection();
       }
     }
   
     for(QList<Port>::iterator it=port_south.begin(); it!=port_south.end(); ++it){
       portX = it->get_x() ;
       portY = it->get_y() ;
       if(mouseX >= portX - 15 + MARGEX && mouseY >= portY - 15 + MARGEY && mouseX <= portX + 15 +MARGEX && mouseY <= portY + 15 + MARGEY){
	 b3 = true;
	 s2 = it->getName();
	 comm = it->getComment();
	 type = it->getDirection();
       }
     }
     if(b3){
       b = false;
       erase_line(ln,lname);
       write_type(type);
       erase_comment();
       write_comment(comm);
       write_name("signal",s2);
     }
   }
}


/*return to the previous level if back button has been clicked*/
void Window::_back(){
  if(cpt_level==0){
    QMessageBox *m = new QMessageBox(this);
    m->setText("can't go up, you're on the top level !");
    m->addButton("ok",QMessageBox::YesRole);
    m->show();  
  }
  
  else{
    this->setDisabled(true);
    paint = false;
    repaint();
    cpt_level--;
    mess_charg = new QWidget();
    mess_charg->setFixedSize(200,50);
    mess_charg->move(200,50);
    charg_open = true;
    QBoxLayout *b = new QBoxLayout(QBoxLayout::TopToBottom,0);
    QLabel *l = new QLabel();
    l->setText("please wait while charging");
    b->addWidget(l);
    mess_charg->setLayout(b);
    mess_charg->show();
    
    p = base->get_BasePos(father.toStdString());
    entity = p.getEntity();
    c = new Coord(250,250,250,250);
    port_east = entity->getPortEast(c);
    port_west = entity->getPortWest(c);
    port_north = entity->getPortNorth(c);
    port_south = entity->getPortSouth(c);
    father = tab[cpt_level];
    current = QString::fromStdString(entity->getName());
    paint = true;
    repaint();
    this->setDisabled(false);
    component_clicked = false;
  }
}

