#include "QCameraWidget.h"
#include <sstream>
#include <iostream>

    QCameraWidget::QCameraWidget(QWidget *pparent) : BasicGlCamera(pparent)
    {
        fBold.resize(1440);
        fEnable.resize(1440);
        fBold.assign(1440, false);
        fEnable.assign(1440, true);
        lastFace = -1;

        CalculatePixelsColor();

   }

    void QCameraWidget::paintGL()
    {
        glClear(GL_COLOR_BUFFER_BIT);
         glLoadIdentity();

         glTranslatef(0,-0.44,0);
         glRotatef(cameraRotation, 0,0,-1);
         if (cameraRotation == 90)
         {
             glTranslatef(-0.45,-0.45,0);
  //           cout << "correction" << endl;
         }
         if (cameraRotation == -90)
         {
             glTranslatef(0.45,-0.45,0);
         }
         glScalef(1.5, 1.5, 1.5);
         drawCamera(true);

         glLineWidth(1.0f);
         glColor3fv(highlightedPixelsCoulour);
         for (vector<int>::iterator it = highlightedPixels.begin(); it!= highlightedPixels.end(); it++)
         {
             drawHexagon(*it, false);
         }
         drawPatches();

        glLineWidth(1.0f);

        //glColor3f(1.f - pixelsColor[fWhite][0],1.f - pixelsColor[fWhite][1],1.f - pixelsColor[fWhite][2]);
        if (fWhite != -1)
        {
            glColor3f(1.f, 0.f, 0.f);
            drawHexagon(fWhite, false);
        }
        DrawCameraText();

        DrawScale();

//        if (linearButton->isVisible())
//            repaintInterface();
    }
    void QCameraWidget::drawCamera(bool alsoWire)
    {
        if (!pixelColorUpToDate)
            CalculatePixelsColor();
        glLineWidth(1.0);
        for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
        {
            glColor3fv(pixelsColor[i]);
            glLoadName(i);
            drawHexagon(i,true);
        }
        if (!alsoWire)
            return;
        glColor3fv(pixelContourColour);//0.0f,0.0f,0.0f);
        for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
        {
            drawHexagon(i, false);
        }
    }
    void QCameraWidget::drawPatches()
    {
        glLineWidth(2.0f);
        glColor3fv(patchesCoulour);
         glBegin(GL_LINES);
                 for (int i=0;i<NTMARK;i++)
                {
                     for (unsigned int j=0;j<patchesIndices[i].size();j++)
                     {
                         glVertex2fv(verticesList[patchesIndices[i][j].first]);
                         glVertex2fv(verticesList[patchesIndices[i][j].second]);
                     }
                 }
         glEnd();

         glColor3fv(highlightedPatchesCoulour);
         glBegin(GL_LINES);
         for (vector<int>::iterator it=highlightedPatches.begin(); it!= highlightedPatches.end(); it++)
         {
             for (unsigned int j=0;j<patchesIndices[*it].size();j++)
             {
                 glVertex2fv(verticesList[patchesIndices[*it][j].first]);
                 glVertex2fv(verticesList[patchesIndices[*it][j].second]);
             }
         }
         glEnd();
         if (fWhitePatch != -1)
         {
             glColor3f(1.f, 0.5f, 0.f);//patchColour);//[0],patchColour[1],patchColour[2]);//0.5f, 0.5f, 0.3f);
             glBegin(GL_LINES);
             for (unsigned int j=0;j<patchesIndices[fWhitePatch].size();j++)
             {
                 glVertex2fv(verticesList[patchesIndices[fWhitePatch][j].first]);
                 glVertex2fv(verticesList[patchesIndices[fWhitePatch][j].second]);
             }
             glEnd();
         }

    }
    void QCameraWidget::Reset()
    {
        fBold.assign(1440, false);
    }

    void QCameraWidget::mousePressEvent(QMouseEvent *cEvent)
    {
        if (cEvent->pos().x() > width()-(width()/50.f))
        {
            toggleInterfaceDisplay();
            return;
        }
        int face = PixelAtPosition(cEvent->pos());
        if (face != -1) {
            fWhite = face;
            fWhitePatch = pixelsPatch[fWhite];
 //           CalculatePatchColor();
            emit signalCurrentPixel(face);
            }
        else
        {
            fWhite = -1;
            fWhitePatch = -1;
        }
        updateGL();
   }
    void QCameraWidget::mouseMoveEvent(QMouseEvent* cEvent)
    {
        int face = PixelAtPosition(cEvent->pos());
        if (face != -1 && lastFace != face) {
            emit signalPixelMoveOver(face);
        }
        lastFace = face;
    }
    void QCameraWidget::mouseDoubleClickEvent(QMouseEvent* cEvent)
    {
        int face = PixelAtPosition(cEvent->pos());
        if (face != -1) {
 //           cout << "Event !" << endl;
            fWhite = face;
             fWhitePatch = pixelsPatch[fWhite];
           highlightPixel(face);
            highlightPatch(fWhitePatch);
 //           CalculatePatchColor();
            emit signalPixelDoubleClick(face);
       }
        else
        {
            fWhite = -1;
            fWhitePatch = -1;
            clearHighlightedPixels();
            clearHighlightedPatches();
        }
        updateGL();

    }

    void QCameraWidget::SetEnable(int idx, bool b)
     {
         fEnable[idx] = b;
     }

     double QCameraWidget::GetData(int idx)
     {
         return fData[idx];
     }
     const char* QCameraWidget::GetName()
     {
         return "QCameraWidget";
     }
     char *QCameraWidget::GetObjectInfo(int px, int py)
     {

         static stringstream stream;
         static string str;
         const int pixel = this->PixelAtPosition(QPoint(px, py));
         if (pixel >= 0)
         {
             stream << "Pixel=" << pixel << "   Data=" << fData[pixel] << '\0';
         }
         str = stream.str();
         return const_cast<char*>(str.c_str());
     }
     void QCameraWidget::CalculatePixelsColor()
     {
         double dmin = fData[0];
          double dmax = fData[0];
          if (fMin < 0 || fMax < 0)
          {
              for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
              {
                  if (!fEnable[i]) continue;
                  if (fData[i] > dmax) dmax = fData[i];
                  if (fData[i] < dmin) dmin = fData[i];
              }
          }
          if (fMin >= 0) dmin = fMin;
          if (fMax >= 0) dmax = fMax;
//          cout << "min: " << dmin << " max: " << dmax << " fMin: " << fMin << " fMax: " << fMax << endl;
          float color;
          for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
           {
              if (!fEnable[i])
              {
//                  cout << "not enabled !" << i << endl;
                  pixelsColor[i][0] = 0.1f;
                  pixelsColor[i][1] = 0.1f;
                  pixelsColor[i][2] = 0.15f;
                  continue;
              }
              if (fData[i] < dmin)
               {
                   pixelsColor[i][0] = tooLowValueCoulour[0];
                   pixelsColor[i][1] = tooLowValueCoulour[1];
                   pixelsColor[i][2] = tooLowValueCoulour[2];
                   continue;
               }
               if (fData[i] > dmax)
               {
                   pixelsColor[i][0] = tooHighValueCoulour[0];
                   pixelsColor[i][1] = tooHighValueCoulour[1];
                   pixelsColor[i][2] = tooHighValueCoulour[2];
                   continue;
               }
               color = float((fData[i]-dmin)/(dmax-dmin));
               if (logScale)
               {
                   color *= 9;
                   color += 1;
                   color = log10(color);
               }

               int index = 0;
               while (ss[index] < color && index < 4)
                   index++;
               index--;
               if (index < 0) index = 0;
               float weight0 = (color-ss[index]) / (ss[index+1]-ss[index]);
               if (weight0 > 1.0f) weight0 = 1.0f;
               if (weight0 < 0.0f) weight0 = 0.0f;
               float weight1 = 1.0f-weight0;
               pixelsColor[i][0] = weight1*rr[index] + weight0*rr[index+1];
               pixelsColor[i][1] = weight1*gg[index] + weight0*gg[index+1];
               pixelsColor[i][2] = weight1*bb[index] + weight0*bb[index+1];
          }
          CalculatePatchColor();
          UpdateText();
          pixelColorUpToDate = true;
     }
     void QCameraWidget::CalculatePatchColor()
     {
         return;
         //calculate the patch contour color. let's use the anti-colour of the pixels
         GLfloat averagePatchColour[3] = {0.0f,0.0f,0.0f};
         for (int i=0;i<9;i++)
             for (int j=0;j<3;j++)
                 averagePatchColour[j] += pixelsColor[softwareMapping[patches[fWhitePatch][i]]][j];
         for (int j=0;j<3;j++)
             averagePatchColour[j] /= 9;
         for (int j=0;j<3;j++)
             patchColour[j] = 1.0f - averagePatchColour[j];
     }
     void QCameraWidget::SetData(const valarray<double> &ddata)
     {
//             fData = ddata;
         for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
             fData[i] = ddata[i];
         pixelColorUpToDate = false;
         if (isVisible())
             updateGL();
     }


     void QCameraWidget::highlightPixel(int idx)
     {
         if (idx < 0 || idx > ACTUAL_NUM_PIXELS)
         {
           cout << "Error: requested pixel highlight out of bounds" << endl;
           return;
         }
         highlightedPixels.push_back(idx);
         if (isVisible())
             updateGL();
     }
     void QCameraWidget::highlightPatch(int idx)
     {
         if (idx < 0 || idx > NTMARK)
         {
             cout << "Error: requested patch highlight out of bounds" << endl;
             return;
         }
         highlightedPatches.push_back(idx);
         if (isVisible())
             updateGL();

     }
     void QCameraWidget::clearHighlightedPatches()
     {
         highlightedPatches.clear();
         if (isVisible())
             updateGL();
     }
     void QCameraWidget::clearHighlightedPixels()
     {
         highlightedPixels.clear();
         if (isVisible())
             updateGL();
     }




