#include "imagegraphicsscene.h"

void ImageGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    /*
     * Erase the selected RectangleDraw
     */
    if(event->button()==Qt::LeftButton&&eraseButton==true){

       mouseLeftPressed=true;
       UserPoint=event->scenePos();

       if(list.size()==0){
       }else{

           int j=0;
           while(j!=(list.size())){
               RectangleDraw *buf=list.at(j);

               if(this->Iscontaining(buf,UserPoint)==true){
                   remove=new RemoveConfirmationWindow(buf,this,&list);
                   break;
               }
               else{
                   j=j+1;
               }
           }
           j=0;
       }
    }

   /*
    * In "Draw mode", changes the state of variable mouseLeftPressed from false to true
    */
   if(event->button()==Qt::LeftButton&&drawButton==true){

       mouseLeftPressed=true;
       origPoint=event->scenePos();
       this->view->setCursor(Qt::CrossCursor);

   }else{

       UserPoint=event->scenePos();
       this->doubleClick=false;
       int j=0;
       while(j!=(list.size())){

          // Each element of the list is a rectangle
          RectangleDraw* buf=list.at(j);
          if(this->Iscontaining(buf,UserPoint)==true){

              break;
          }
          else{
             j=j+1;
             this->doubleClick=false;
          }
       }
       j=0;
   }

   /*
    * Check if the mouse is over one of the rectangles
    */
   if(modifyButton==true){

       mouseLeftPressed=true;
       this->doubleClick=false;
       int j=0;
       while(j!=(list.size())){

          // Each element of the list is a rectangle
          RectangleDraw* buf=list.at(j);
          if(this->Iscontaining(buf,UserPoint)==true){

              this->rectModified=buf;
              this->modifyButton=false;
              this->isSelected=true;

              buf->setFlag(QGraphicsItem::ItemIsSelectable,true);

              break;
          }
          else{
              buf->setFlag(QGraphicsItem::ItemIsSelectable,false);
              j=j+1;
              this->doubleClick=false;
          }
       }
       j=0;

   }else{
   }

   /*
    * Check if the mouse is pressed on one of the rectangle's corners.
    */
   if(isSelected==true&&isOnCorner==true){
      this->checkMousePress(event->scenePos());
   }else{}

   /*
    * If the user is dragging the corner in order to modify the rectangle,
    * allow him to proceed so.
    */
    if(isOnTopRightCornerPressed==true||isOnTopLeftCornerPressed==true||isOnBottomLeftCornerPressed==true||
            isOnBottomRightCornerPressed==true)
    {
        UserPoint=event->scenePos();
        this->startModifying=true;

    }else{}

   QGraphicsScene::mousePressEvent(event);

}

void ImageGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event){

     // Check if the user is pressing the left button
     if(mouseLeftPressed==false&&drawButton==false&&eraseButton==false&&dragButton==false&&modifyButton==false){

         this->doubleClick=true;

        UserPoint=event->scenePos();
          int j=0;
          while(j!=(list.size())){

           // Each element of the list is a rectangle
           RectangleDraw* buf=list.at(j);
           if(this->Iscontaining(buf,UserPoint)==true){

               window=new RectangleWindow(buf,filewriter,this);
               break;
           }
           else{
               j=j+1;
           }
        }
        j=0;
        }else{
         }
      QGraphicsScene::mouseDoubleClickEvent(event);
}

void ImageGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if(isSelected==true){
       this->checkMouseMove(event->scenePos());
    }

    if(startModifying==true){

      if(isOnTopLeftCornerPressed==true){
          QRectF rectF_buffer(rectModified->rect().bottomRight().x(),rectModified->rect().bottomRight().y(),
                              event->scenePos().x()-rectModified->rect().bottomRight().x(),
                              event->scenePos().y()-rectModified->rect().bottomRight().y());
          if(rectF_buffer.height()<0){
              rectModified->setRect(rectF_buffer.normalized());
          }else{
          }

          if(rectF_buffer.height()<0){

              rectModified->setRect(rectF_buffer.normalized());
          }else{
          }
          rectModified->setFlag(QGraphicsItem::ItemIsSelectable,false);
          this->modifyButton=false;
          this->isSelected=false;
          if(rectModified->getItem()!=NULL){
             rectModified->getItem()->setPos(rectModified->rect().topLeft());
          }
      }
      if(isOnTopRightCornerPressed==true){
          QRectF rectF_buffer(rectModified->rect().bottomLeft().x(),rectModified->rect().bottomLeft().y(),
                              event->scenePos().x()-rectModified->rect().bottomLeft().x(),
                              event->scenePos().y()-rectModified->rect().bottomLeft().y());
          rectModified->setRect(rectF_buffer.normalized());
          rectModified->setFlag(QGraphicsItem::ItemIsSelectable,false);
          this->modifyButton=false;
          this->isSelected=false;
          if(rectModified->getItem()!=NULL){
             rectModified->getItem()->setPos(rectModified->rect().topLeft());
          }
      }
      if(isOnBottomLeftCornerPressed==true){

          QRectF rectF_buffer(rectModified->rect().topRight().x(),rectModified->rect().topRight().y(),
                              event->scenePos().x()-rectModified->rect().topRight().x(),
                              event->scenePos().y()-rectModified->rect().topRight().y());
          rectModified->setRect(rectF_buffer.normalized());
          rectModified->setFlag(QGraphicsItem::ItemIsSelectable,false);
          this->modifyButton=false;
          this->isSelected=false;
          if(rectModified->getItem()!=NULL){
             rectModified->getItem()->setPos(rectModified->rect().topLeft());
          }
      }

      if(isOnBottomRightCornerPressed==true){

          QRectF rectF_buffer(rectModified->rect().topLeft().x(),rectModified->rect().topLeft().y(),
                              event->scenePos().x()-rectModified->rect().topLeft().x(),
                              event->scenePos().y()-rectModified->rect().topLeft().y());
          rectModified->setRect(rectF_buffer.normalized());
          rectModified->setFlag(QGraphicsItem::ItemIsSelectable,false);
          if(rectModified->getItem()!=NULL){
             rectModified->getItem()->setPos(rectModified->rect().topLeft());
          }

          this->modifyButton=false;
          this->isSelected=false;
      }

    }else{

    }

    /*
     * Draw the Rectangle
     */
    if(mouseLeftPressed==true&&drawButton==true){

      if(!rect){
          rect=new RectangleDraw;
          this->addItem(rect);
          rect->setPen(QPen(Qt::red,4,Qt::SolidLine));
          rect->setId(id=id+1);
      }

      // The normalized method allow the user to  draw rectangles having a negative height/width
      // Remember: The top-left point is in the rectangle's local coordinates !!!
      QRectF rectangleF(origPoint.x(),origPoint.y(),event->scenePos().x()-origPoint.x(),event->scenePos().y()-origPoint.y());

      rect->setRectF(rectangleF);
      rect->setRect(rectangleF.normalized());

      // The top-Left point is in local rectangle's coordinates. Therefore, we have to transform them in scene's absolute
      // coordinates using mapToScene.
      QPointF point;
      point=rect->mapToScene(rect->rect().topLeft());
      rect->setPoint(point);

    } else{
      }
        QGraphicsScene::mouseMoveEvent(event);
}

// Check if the mouse is over one of the rectangle corners
int ImageGraphicsScene::checkMouseMove(QPointF point){

     if((this->rectModified)!=NULL){
        // Position of mouse pointer
        qreal point_x=point.x();
        qreal point_y=point.y();

        // Position of rectangle corners
        qreal top_right_x;
        qreal top_right_y;
        qreal bottom_left_y;
        qreal bottom_left_x;
        qreal bottom_right_x;
        qreal bottom_right_y;
        qreal top_left_x;
        qreal top_left_y;

        top_right_x=rectModified->rect().topRight().x();
        top_right_y=rectModified->rect().topRight().y();
        bottom_left_y=rectModified->rect().bottomLeft().y();
        bottom_left_x=rectModified->rect().bottomLeft().x();
        bottom_right_x=rectModified->rect().bottomRight().x();
        bottom_right_y=rectModified->rect().bottomRight().y();
        top_left_x=rectModified->rect().topLeft().x();
        top_left_y=rectModified->rect().topLeft().y();

        // Check if the mouse is around one of the rectangle's corner points
        if(point_x>=top_left_x-10&&point_x<=top_left_x+10&&point_y>=top_left_y-10&&point_y<=top_left_y+10){
            this->view->setCursor(Qt::SizeFDiagCursor);
            this->update();
            this->isOnCorner=true;
            return 0;
         }
         else if(point_x>=top_right_x-10&&point_x<=top_right_x+10&&point_y>=top_right_y-10&&point_y<=top_right_y+10){
            this->view->setCursor(Qt::SizeBDiagCursor);
            this->update();
            this->isOnCorner=true;
            return 0;
         }
         else if(point_x>=bottom_left_x-10&&point_x<=bottom_left_x+10&&point_y>=bottom_left_y-10&&point_y<=bottom_left_y+10){
            this->view->setCursor(Qt::SizeBDiagCursor);
            this->update();
            this->isOnCorner=true;
            return 0;
         }
         else if(point_x>=bottom_right_x-10&&point_x<=bottom_right_x+10&&point_y>=bottom_right_y-10&&point_y<=bottom_right_y+10){
            this->view->setCursor(Qt::SizeFDiagCursor);
            this->update();
            this->isOnCorner=true;
            return 0;
         }

         else{
            this->view->setCursor(Qt::ArrowCursor);
            this->update();
            this->isOnCorner=false;
            return 0;
         }
        this->isOnCorner=false;
        return 0;
     }
     else{
         return 0;
     }

}

// Check if the user has pressed one of the rectangle borders
int ImageGraphicsScene::checkMousePress(QPointF point){

   if((this->rectModified)!=NULL){
      // Position of mouse pointer
      qreal point_x=point.x();
      qreal point_y=point.y();

      // Position of rectangle corners
      qreal top_right_x;
      qreal top_right_y;
      qreal bottom_left_y;
      qreal bottom_left_x;
      qreal bottom_right_x;
      qreal bottom_right_y;
      qreal top_left_x;
      qreal top_left_y;

      // Coordinates of the rectangle which is going to be modified
      top_right_x=rectModified->rect().topRight().x();
      top_right_y=rectModified->rect().topRight().y();
      bottom_left_y=rectModified->rect().bottomLeft().y();
      bottom_left_x=rectModified->rect().bottomLeft().x();
      bottom_right_x=rectModified->rect().bottomRight().x();
      bottom_right_y=rectModified->rect().bottomRight().y();
      top_left_x=rectModified->rect().topLeft().x();
      top_left_y=rectModified->rect().topLeft().y();

      // Check if the mouse is around one of the rectangle's corner points
      if(point_x>=top_left_x-10&&point_x<=top_left_x+10&&point_y>=top_left_y-10&&point_y<=top_left_y+10){
         this->update();
         this->isOnTopLeftCornerPressed=true;
         return 0;
       }
       else if(point_x>=top_right_x-10&&point_x<=top_right_x+10&&point_y>=top_right_y-10&&point_y<=top_right_y+10){
         this->update();
         this->isOnTopRightCornerPressed=true;
         return 0;
       }
       else if(point_x>=bottom_left_x-10&&point_x<=bottom_left_x+10&&point_y>=bottom_left_y-10&&point_y<=bottom_left_y+10){
         this->update();
         this->isOnBottomLeftCornerPressed=true;
         return 0;
       }
       else if(point_x>=bottom_right_x-10&&point_x<=bottom_right_x+10&&point_y>=bottom_right_y-10&&point_y<=bottom_right_y+10){
         this->update();
         this->isOnBottomRightCornerPressed=true;
         return 0;
       }

       else{
          this->update();
          this->isOnTopLeftCornerPressed=false;
          this->isOnTopRightCornerPressed=false;
          this->isOnBottomLeftCornerPressed=false;
          this->isOnBottomRightCornerPressed=false;
          return 0;
       }
      this->isOnTopLeftCornerPressed=false;
      this->isOnTopRightCornerPressed=false;
      this->isOnBottomLeftCornerPressed=false;
      this->isOnBottomRightCornerPressed=false;
      return 0;
   }
   else{
       return 0;
   }

}

void ImageGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){

    if (mouseLeftPressed==true&&drawButton==true){
        this->list.append(rect);
    }else{
    }
    this->rect=NULL;

    this->mouseLeftPressed=false;
    this->doubleClick=true;
    this->dragButton=false;

    if (startModifying==true){
        this->startModifying=false;
        this->modifyButton=true;
        this->isOnTopLeftCornerPressed=false;
        this->isOnTopRightCornerPressed=false;
        this->isOnBottomLeftCornerPressed=false;
        this->isOnBottomRightCornerPressed=false;
        this->view->setCursor(*this->getModifyCursor());
    }

    QGraphicsScene::mouseReleaseEvent(event);
}

bool ImageGraphicsScene::Iscontaining(RectangleDraw *rectangle,QPointF point)const{

    if((rectangle)!=NULL){
       if(rectangle->rect().topLeft().x()<point.x() && (rectangle->rect().topLeft().x()+rectangle->rect().width())>point.x() && rectangle->rect().topLeft().y()<point.y() && (rectangle->rect().topLeft().y()+rectangle->rect().height())>point.y()){
          return true;
       }
       else{
          return false;
       }
       return false;
     }
     else{
       return false;
     }
}

void ImageGraphicsScene::setDrawButton(bool value){
    this->eraseButton=false;
    this->drawButton=value;
}

void ImageGraphicsScene::setEraseButton(bool value){
    this->drawButton=false;
    this->eraseButton=value;
}

bool ImageGraphicsScene::getDrawButton()const{
    return drawButton;
}

bool ImageGraphicsScene::getEraseButton()const{
    return eraseButton;
}

void ImageGraphicsScene::setDoubleClick(bool value){
    this->doubleClick=value;
}

bool ImageGraphicsScene::getDoubleClick()const{
    return doubleClick;
}

void ImageGraphicsScene::setDragButton(bool value){
    this->dragButton=value;
}

bool ImageGraphicsScene::getDragButton()const{
    return dragButton;
}

bool ImageGraphicsScene::checkModify()const{
    return modifyButton;
}

void ImageGraphicsScene::setModify(bool state){
    this->modifyButton=state;
}

QCursor* ImageGraphicsScene::getEraseCursor()const{
    return erase_cursor;
}

QCursor *ImageGraphicsScene::getModifyCursor()const{
    return modify_cursor;
}

QList<RectangleDraw*> ImageGraphicsScene::getList()const{
    return list;
}

FileWriter* ImageGraphicsScene::getFileWriter()const{
    return this->filewriter;
}


void ImageGraphicsScene::setIsSelected(bool state){
    this->isSelected=state;
}

CreateFileAbstraction* ImageGraphicsScene::getCreateFileAbstraction()const{
    return createfileabstraction;
}

void ImageGraphicsScene::setList(QList<RectangleDraw *> list_1){
    this->list=list_1;
}

void ImageGraphicsScene::setId(int id){
    this->id=id;
}

void ImageGraphicsScene::setCreateFileAbstraction(CreateFileAbstraction *createfileabstraction_1){
    this->createfileabstraction=createfileabstraction_1;
}

void ImageGraphicsScene::setFileWriter(FileWriter *filewriter_1){
    this->filewriter=filewriter_1;
}

