#include <iostream>

#include <q3picture.h>
#include "qmetapicture.h"
#include <qpainter.h>
#include <qpoint.h>
#include <qapplication.h>
#include <qclipboard.h>
#include <qevent.h>
//Added by qt3to4:
#include <QMouseEvent>

QMetaPictureList::QMetaPictureList()
{
}

QMetaPictureList::~QMetaPictureList()
{
}



QMetaPicture* QMetaPictureList::getSelected()
{
  std::list<QMetaPicture*>::iterator it;
  for(it=list.begin();it!=list.end();it++)
  {
    if( (*it)->isSelected() )
    {
      return (*it);
    }
  }

  return NULL;
}



void QMetaPictureList::push_back(QMetaPicture* pic)
{
  list.push_back(pic);
}

void  QMetaPictureList::draw(QPainter* p)
{
  std::list<QMetaPicture*>::iterator it;
  for(it=list.begin();it!=list.end();it++)
  {
    (*it)->draw(p);
  }

}

QMetaPicture::QMetaPicture(const char* data, unsigned int size)
{

  m_picture= new Q3Picture();
  m_picture->setData(data,size);

  m_selected=false;

  m_movemode=8; //global movement

  m_scale.x=m_scale.y=1.0f;


}
QMetaPicture::~QMetaPicture()
{}
/** No descriptions */
void QMetaPicture::draw(QPainter* p)
{

  p->save();
  
  //p->scale(m_scale.x,m_scale.y);
  p->translate(m_translate.x,m_translate.y);


  QRect rect;
  rect.setCoords(50,50,100,100);
  p->drawPicture(*m_picture);
  if(m_selected)
    p->setPen(QColor(255,0,0));
  else
    p->setPen(QColor(0,0,0));
  if(m_selected) drawRect(p); 
    p->restore();


}

QRect QMetaPicture::getBoundingRect()
{
  QRect rect= m_picture->boundingRect();
  rect.setLeft(rect.left()-2);
  rect.setRight(rect.right()+2);
  rect.setTop(rect.top()-2);
  rect.setBottom(rect.bottom()+2);
  return rect;
}


/** No descriptions */
bool QMetaPicture::contains(const QPoint& point)
{

  QRect rect=translateRect(m_picture->boundingRect());


  return rect.contains(translatePoint(point));
}

QPicMimeSource::QPicMimeSource(Q3Picture* picture)
{


  m_size=picture->size();
  m_data= new char[m_size];
  const char* data=picture->data();
  for(unsigned int i=0;i<m_size;i++)
  {
    m_data[i]=data[i];
  }



}
QPicMimeSource::~QPicMimeSource()
{

  delete [] m_data;
}
/** No descriptions */
QByteArray QPicMimeSource::encodedData(const char* data) const
{

  QString type(data);
  QByteArray b;
  if(type=="image/x-svg+xml" || type=="image/x-svg") //return a svg file
  {
    Q3Picture pic;
    pic.setData(m_data,m_size);

    QBuffer w(b);
    w.open(QIODevice::WriteOnly);
    pic.save(&w,"svg");
    w.close();

  }
  else //return the  QPicture  data
  {

    QBuffer w(b);
    w.open( QIODevice::WriteOnly );
    w.writeBlock(m_data,m_size);
    w.close();

  }
  return b;

}

const char* QPicMimeSource::format(int i) const
{
  // std::cout <<"format"<<std::endl;
  switch(i)
  {
  case 0:
    return "image/x-vnd.trolltech.qpicture";
  case 1:
    return "image/x-svg+xml";
  default:
    return 0;
  }

}

void QPicMimeSource::copy()
{

  QClipboard *cb = QApplication::clipboard();
  cb->setData(this,QClipboard::Clipboard);
}

bool QPicMimeSource::provides(const char* format)
{
  QString str(format);
  if(str=="image/x-vnd.trolltech.qpicture")
    return true;
  if(str=="image-svg+xml")
    return true;

  return false;
}

bool QPicMimeSource::canDecode(const char* format)
{
  return provides(format);
}

/** No descriptions */
void QMetaPicture::drawRect(QPainter* p){

  QRect current=getBoundingRect();
  p->drawRect(current);
  
  int left=current.left();
  int right=current.right();
  int top=current.top();
  int bottom=current.bottom();
  int width=5;
  int middleh= qRound( (left+right)/2.0f );
  int middlev= qRound( (top+bottom)/2.0f);

//  activerect[0].setCoords(left,top,left+width,top+width);
//  activerect[1].setCoords(middleh-width,top,middleh+width,top+width);
//  activerect[2].setCoords(right-width,top,right,top+width);
//  activerect[3].setCoords(left,middlev-width,left+width,middlev+width);
  activerect[4].setCoords(right-width,middlev-width,right,middlev+width);
//  activerect[5].setCoords(left,bottom-width,left+width,bottom);
  activerect[6].setCoords(middleh-width,bottom-width,middleh+width,bottom);
  activerect[7].setCoords(right-width,bottom-width,right,bottom);

  for(int i=0;i<8;i++)
    p->drawRect(activerect[i]);
  
}
/** No descriptions */
void QMetaPictureList::mousePressEvent(QMouseEvent* e){



  std::list<QMetaPicture*>::reverse_iterator it;

  for(it=list.rbegin();it!=list.rend();it++)
  {
      (*it)->mousePressEvent(e);
  }
}

/** No descriptions */
void QMetaPictureList::mouseMoveEvent(QMouseEvent* e){

  QMetaPicture* p=getSelected();
  if(p) p->mouseMoveEvent(e);
}

/** No descriptions */
void QMetaPicture::mousePressEvent(QMouseEvent* e){

  QPoint pos=e->pos();
  QPoint tpos=translatePoint(e->pos());

  int i;
  for(i=0;i<8;i++)
  {
    QRect trect=translateRect(activerect[i]);
    if(trect.contains(pos))
      break;
    
  }
  m_movemode=i;
  if(m_movemode==8)
  {
    QRect trect=translateRect(m_picture->boundingRect());
    if(!trect.contains(pos))
    {  m_movemode=-1;
       m_selected=false;
    }
    else
    {
      m_selected=true;
    }
  }

  m_oldpoint=pos;

  
}
/** No descriptions */
void QMetaPicture::mouseMoveEvent(QMouseEvent* e){

  QPoint displacement=e->pos()-m_oldpoint;
  QRect rect=m_picture->boundingRect();
  int left=rect.left();
  int right=rect.right();
  int top=rect.top();
  int bottom=rect.bottom();

  QPoint scaledpoint=translatePoint(e->pos());
  switch(m_movemode)
  {
    case 4:  //right side
    /*right=qRound(right*m_scale.x+m_translate.x+m_scaletranslation.x);
    m_scale.x=( scaledpoint.x() -(left) )/(float)(right - (left) );
    m_scaletranslation.x= -qRound( (left*m_scale.x-left) );  */
    resolveVectors(left,right,e->pos(),0);
    break;
    case 6:  //bottom
    /*bottom=qRound(bottom*m_scale.y+m_translate.y+m_scaletranslation.y);
    m_scale.y= (scaledpoint.y()-(top))/(float)(bottom-(top));
    m_scaletranslation.y= -qRound( (top*m_scale.y-top) ); */
    resolveVectors(top,bottom,e->pos(),1);
    break;
    case 7:
    /*right=qRound(right*m_scale.x+m_translate.x+m_scaletranslation.x);
    m_scale.x=( scaledpoint.x() -(left+m_translate.x) )/(float)(right -(left+m_translate.x));
    m_scaletranslation.x= -qRound( (left*m_scale.x-left) );
    bottom=qRound(bottom*m_scale.y+m_translate.y+m_scaletranslation.y);
    m_scale.y= (scaledpoint.y()-(top+m_translate.y))/(float)(bottom-(top+m_translate.y));
    m_scaletranslation.y= -qRound( (top*m_scale.y-top) );  */
    resolveVectors(left,right,e->pos(),0);
    resolveVectors(top,bottom,e->pos(),1);
    break;
    case 8:
    m_translate.x+=displacement.x();
    m_translate.y+=displacement.y();
    break;
    default:
    break;
  }

  m_oldpoint=e->pos();
    
    
}

/** No descriptions */
QPoint QMetaPicture::translatePoint(const QPoint&  point){

  QPoint newpoint(point);
  newpoint.setX( point.x()+m_translate.x );
  newpoint.setY( point.y()+m_translate.y );

  return newpoint;
}

QRect QMetaPicture::translateRect(const QRect& rect){
  QRect newrect;
  newrect.setCoords(rect.left()+m_translate.x,
  rect.top()+m_translate.y,
  rect.right()+m_translate.x,
  rect.bottom()+m_translate.y );
  
  return newrect;
}
/** No descriptions */
void QMetaPicture::resolveVectors(int a, int b,const QPoint& point,bool coord){

  float g;
  int n;
  if(!coord)
  {
      g=m_translate.x;
      n=point.x();
  }
  else
  {
    g=m_translate.y;
    n=point.y();
    }
  float t=(a+g)*(b+g-n)/(float)(n-a-g);
  float scale=(a+g)/(float)(a+g+t);

  if(!coord)
  {
    m_scale.x=scale;
    m_scaletranslation.x=qRound(t);
  }
  else
  {
    m_scale.y=scale;
    m_scaletranslation.y=qRound(t);
  }

    
}
