#include "OrderWidget.h"


OrderWidget::OrderWidget(int places[], const QStringList &dimnames)
{
   dims=3;
   slot=2;

   labelHeight = 20;
   movedNr = -1; // none selected to move
   //this->setFrameStyle(QFrame::Box);
   memcpy(place, places, dims * slot * sizeof(int));

   int count=0;
   for (int i=0; i<dimnames.size(); ++i) {
      int len = dimnames.at(i).length();
      if ((len > 0) && (len <= 2)) // label can be displayed?
         count++;
   }
   if (count == dimnames.size()) {
      for (int i=0; i<dimnames.size(); ++i)
         this->dimnames.append(dimnames.at(i));
   } else {
      for (int i=0; i<dimnames.size(); ++i)
         this->dimnames.append(QString::number(i+1));
   }
}

QSize OrderWidget::minimumSizeHint () const {
   int h = this->fontMetrics().height();
   return QSize(dims*slot*2*h, 2*labelHeight);
}

/**
  returns the selected order: vector with 3 elements
  each element contains one or two dimension numbers, which will be merged
  */
std::vector<std::vector<int> > OrderWidget::getValues() const
{
   std::vector<std::vector<int> > val;
   int count = 0;
   for (int i=0; i<dims; i++) {
      std::vector<int> line;
      for (int j=0; j<slot; j++) {
         int dim = place[i*slot+j];
         if (dim >= 0) {
            count++;
            line.push_back(dim);
         }
      }
      if (line.size() > 0) val.push_back(line);
   }
   /*
   // 3 dims have to be used
   for (int i=0; i<(int)val.size()-1; i++) {
      if (val[i].size() == 0)
         val.clear(); // set not valid
   }*/
   return val;
}

void OrderWidget::mousePressEvent(QMouseEvent* event) {
   int x = event->x();
   int pos = x/width;
   if ((pos < 0) || (pos >= dims*slot))
      movedNr = -1;
   else if (place[pos] < 0)
      movedNr = -1;
   else
      movedNr = pos;
}

void OrderWidget::mouseMoveEvent(QMouseEvent* event) {
   currentX = event->x();
   repaint();
}

/**
  elements are swapped, if mouse is pressed on one element and released on onother
  */
void OrderWidget::mouseReleaseEvent(QMouseEvent* ) {
   if (movedNr < 0 ) return; // no element selected

   int current = currentX / width;
   if ((current >= 0) && (current < dims*slot)) // new position ok?
   {
      int old = place[current];
      place[current] = place[movedNr];
      place[movedNr] = old;
      emit foldingDimensionsChanged();
   }
   movedNr = -1;
   repaint();
}

void OrderWidget::drawElement(QPainter &painter, int x, int elemnr) {
   int w=rect().height()/10;
   int height = rect().height() - labelHeight;
   QRect rect(x+w, labelHeight + w, width-2*w, height-2*w);

   painter.setPen(Qt::black);

   painter.fillRect( x+w, labelHeight + w, width-2*w, height-2*w, Qt::gray);
   painter.drawRect( x+w, labelHeight + w, width-2*w, height-2*w);
   painter.drawText(rect, Qt::AlignCenter, dimnames.at(elemnr));
}

void OrderWidget::paintEvent(QPaintEvent*) {
   width = rect().width() / (dims*slot);
   QPainter painter(this);
   int height = rect().height() - labelHeight;

   for (int i=0; i<dims; i++) {
      int x = i*2*width;
      int w = (i < dims-1) ? 2*width : rect().width() - x;
      painter.drawRect(QRect(x, 0, w, labelHeight));
   }

   painter.drawRect(rect().adjusted(0, 0, -1, -1));

   for (int i=0; i<dims*slot; i++) {
      int x = i*width;
      int w = (i < dims*slot-1) ? width : rect().width() - x;
      QRect r(x, labelHeight, w, height);

      painter.setPen(Qt::gray);
      painter.drawRect( r );
      painter.drawLine( r.x(), r.y(), r.x()+w, r.y()+height);
      painter.drawLine( r.x()+w, r.y(), r.x(), r.y()+height);

      if (place[i] >= 0) { // draw existing elements
         drawElement(painter, x, place[i]);
      }
   }
   // draw element which is beeing moved on top
   if (movedNr >= 0) {
      int x = currentX-width/2;
      drawElement(painter, x, place[movedNr]);
   }

   QRect r = rect().adjusted(0, labelHeight,-1, -1);
   painter.setPen(Qt::black);
   painter.drawRect(r);

   QString label[] = {"x", "y", "z"};
   for (int i=0; i<dims; i++) {
      int x = i*2*width;
      painter.drawLine(x, r.y(), x, r.y()+height);
      painter.drawText(QRect(x, 0, 2*width, labelHeight), Qt::AlignCenter, label[i]);
   }   

   QStyleOptionFrame option;
   option.initFrom(this);
   //style()->drawPrimitive(QStyle::PE_FrameStatusBar, &option, &painter);
   style()->drawControl(QStyle::CE_PushButton, &option, &painter, this);
}
