/*
 * Q3DCameraWidget.cc
 *
 *  Created on: Aug 26, 2011
 *      Author: lyard
 */
#include "Q3DCameraWidget.h"
#include <math.h>
#include <sstream>

    Q3DCameraWidget::Q3DCameraWidget(QWidget* pparent) : BasicGlCamera(pparent),
                                                         timer(),
                                                         currentLoc(),
                                                         steps(0),
                                                         totalSteps(50),
                                                         currentView(4),
                                                         nextView(currentView),
                                                         cameraViews(0),
                                                         isPicking(false),
                                                         initFinished(false)
    {
        setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
        rotX = rotY = 0;
        timer.setInterval(40.0);//0.04 second interval
        QObject::connect(&timer, SIGNAL(timeout()),
                         this, SLOT(timedUpdate()));
        QObject::connect(this, SIGNAL(dataHasChanged()),
                         this, SLOT(timedUpdate()));
        spheresColors.resize(28);
        spheresRadius.resize(28);
        spheresLocation.resize(28);
        PixelMap mypMap;
        if (!mypMap.Read("FACTmapV5.txt"))
        {
            cerr << "ERROR - Problems reading FACTmapV5.txt" << endl;
            exit(-1);
        }
        ifstream fin1("Trigger-Patches.txt");
        if (!fin1.is_open())
        {
            cout << "Error: file \"Trigger-Patches\" missing. aborting." << endl;
            exit(-1);
        }
        string buf;
        vector<int> patchHW(1440);
        int l = 0;
        while (getline(fin1, buf, '\n'))
        {
            buf = Tools::Trim(buf);
            if (buf[0]=='#')
                continue;

            stringstream str(buf);
            for (int i=0; i<9; i++)
            {
                unsigned int n;
                str >> n;

                if (n>=patchHW.size())
                    continue;

                patchHW[n] = l;
            }
            l++;
        }
        if (l!=160)
            cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;

        assignPixelMap(mypMap);
        assignTriggerPatchesMap(patchHW);
        setTitle("Temperatures");


        for (auto it=spheresColors.begin(), jt = spheresRadius.begin(); it != spheresColors.end(); it++, jt++)
        {
            (*it)[0] = 0.5f;
            (*it)[1] = 0.5f;
            (*it)[2] = 0.5f;
            (*jt) = 0.1f;
        }
        float xx = 0.5;
        float yx = 0.5;
        float z = 0.2;
        float zplus = 0.25;
        //crate
        for (int i=0;i<28;i+=4)
        {
            xx = 0.5*cos((float)(i)*M_PI/4);
            yx = 0.5*sin((float)(i)*M_PI/4);
            spheresLocation[i][0] = xx;
            spheresLocation[i][1] = yx;
            spheresLocation[i][2] = z;

            xx = 0.5*cos((float)(i+1)*M_PI/4);
            yx = 0.5*sin((float)(i+1)*M_PI/4);
            spheresLocation[i+1][0] = xx;
            spheresLocation[i+1][1] = yx;
            spheresLocation[i+1][2] = z + zplus/4;

            xx = 0.5*cos((float)(i+2)*M_PI/4);
            yx = 0.5*sin((float)(i+2)*M_PI/4);
            spheresLocation[i+2][0] = xx;
            spheresLocation[i+2][1] = yx;
            spheresLocation[i+2][2] = z + 2*zplus/4;

            xx = 0.5*cos((float)(i+3)*M_PI/4);
            yx = 0.5*sin((float)(i+3)*M_PI/4);
            spheresLocation[i+3][0] = xx;
            spheresLocation[i+3][1] = yx;
            spheresLocation[i+3][2] = z + 3*zplus/4;
            z += zplus;
        }


        cameraViews.push_back(cameraLocation(45,45, 0.6,-0.3,0));//0
        cameraViews.push_back(cameraLocation(75,0, 0,-0.65,0));//1
        cameraViews.push_back(cameraLocation(45,-45, -0.6,-0.3,0));//2
        cameraViews.push_back(cameraLocation(0,75, 0.8,0,0));//3
        cameraViews.push_back(cameraLocation(0,0, 0,0,1));//4
        cameraViews.push_back(cameraLocation(0,-75, -0.8,0,0));//5
        cameraViews.push_back(cameraLocation(-45,45, 0.6,0.5,0));//6
        cameraViews.push_back(cameraLocation(-75,0, 0,1,0.2));//7
        cameraViews.push_back(cameraLocation(-45,-45, -0.6,0.5,0));//8

        tempPatches.resize(31);
        tempPatches[0].push_back(16);
        tempPatches[0].push_back(24);
        tempPatches[0].push_back(32);
        tempPatches[0].push_back(36);

        tempPatches[1].push_back(49);
        tempPatches[1].push_back(48);
        tempPatches[1].push_back(52);

        tempPatches[2].push_back(4);
        tempPatches[2].push_back(5);
        tempPatches[2].push_back(8);
        tempPatches[2].push_back(9);

        tempPatches[3].push_back(17);
        tempPatches[3].push_back(19);
        tempPatches[3].push_back(18);
        tempPatches[3].push_back(26);
        tempPatches[3].push_back(25);

        tempPatches[4].push_back(37);
        tempPatches[4].push_back(38);
        tempPatches[4].push_back(50);
        tempPatches[4].push_back(51);
        tempPatches[4].push_back(33);
        tempPatches[4].push_back(34);

        tempPatches[5].push_back(65);
        tempPatches[5].push_back(62);
        tempPatches[5].push_back(61);
        tempPatches[5].push_back(54);
        tempPatches[5].push_back(53);

        tempPatches[6].push_back(69);
        tempPatches[6].push_back(68);
        tempPatches[6].push_back(64);
        tempPatches[6].push_back(60);

        tempPatches[7].push_back(2);
        tempPatches[7].push_back(6);
        tempPatches[7].push_back(7);
        tempPatches[7].push_back(12);
        tempPatches[7].push_back(13);
        tempPatches[7].push_back(0);

        tempPatches[8].push_back(10);
        tempPatches[8].push_back(11);
        tempPatches[8].push_back(20);
        tempPatches[8].push_back(21);

        tempPatches[9].push_back(30);
        tempPatches[9].push_back(35);
        tempPatches[9].push_back(39);
        tempPatches[9].push_back(27);
        tempPatches[9].push_back(28);

        tempPatches[10].push_back(40);
        tempPatches[10].push_back(44);
        tempPatches[10].push_back(45);
        tempPatches[10].push_back(55);
        tempPatches[10].push_back(57);

        tempPatches[11].push_back(56);
        tempPatches[11].push_back(63);
        tempPatches[11].push_back(66);
        tempPatches[11].push_back(67);
        tempPatches[11].push_back(71);

        tempPatches[12].push_back(72);
        tempPatches[12].push_back(78);
        tempPatches[12].push_back(76);
        tempPatches[12].push_back(70);
        tempPatches[12].push_back(77);

        tempPatches[13].push_back(159);
        tempPatches[13].push_back(1);
        tempPatches[13].push_back(155);
        tempPatches[13].push_back(3);
        tempPatches[13].push_back(153);
        tempPatches[13].push_back(14);

        tempPatches[14].push_back(23);
        tempPatches[14].push_back(15);
        tempPatches[14].push_back(139);
        tempPatches[14].push_back(22);
        tempPatches[14].push_back(127);
        tempPatches[14].push_back(29);

        tempPatches[15].push_back(111);
        tempPatches[15].push_back(42);
        tempPatches[15].push_back(123);
        tempPatches[15].push_back(31);
        tempPatches[15].push_back(43);
        tempPatches[15].push_back(41);

        tempPatches[16].push_back(103);
        tempPatches[16].push_back(58);
        tempPatches[16].push_back(102);
        tempPatches[16].push_back(59);
        tempPatches[16].push_back(47);
        tempPatches[16].push_back(46);

        tempPatches[17].push_back(95);
        tempPatches[17].push_back(73);
        tempPatches[17].push_back(75);
        tempPatches[17].push_back(74);
        tempPatches[17].push_back(81);
        tempPatches[17].push_back(79);

        tempPatches[18].push_back(93);
        tempPatches[18].push_back(91);
        tempPatches[18].push_back(94);
        tempPatches[18].push_back(100);
        tempPatches[18].push_back(101);

        tempPatches[19].push_back(108);
        tempPatches[19].push_back(109);
        tempPatches[19].push_back(110);
        tempPatches[19].push_back(115);
        tempPatches[19].push_back(121);

        tempPatches[20].push_back(124);
        tempPatches[20].push_back(137);
        tempPatches[20].push_back(126);
        tempPatches[20].push_back(125);
        tempPatches[20].push_back(122);

        tempPatches[21].push_back(152);
        tempPatches[21].push_back(147);
        tempPatches[21].push_back(138);
        tempPatches[21].push_back(143);
        tempPatches[21].push_back(136);

        tempPatches[22].push_back(156);
        tempPatches[22].push_back(158);
        tempPatches[22].push_back(154);
        tempPatches[22].push_back(157);
        tempPatches[22].push_back(151);

        tempPatches[23].push_back(87);
        tempPatches[23].push_back(80);
        tempPatches[23].push_back(92);
        tempPatches[23].push_back(82);
        tempPatches[23].push_back(83);

        tempPatches[24].push_back(144);
        tempPatches[24].push_back(148);
        tempPatches[24].push_back(150);
        tempPatches[24].push_back(149);

        tempPatches[25].push_back(145);
        tempPatches[25].push_back(146);
        tempPatches[25].push_back(141);
        tempPatches[25].push_back(142);
        tempPatches[25].push_back(134);
        tempPatches[25].push_back(135);

        tempPatches[26].push_back(113);
        tempPatches[26].push_back(114);
        tempPatches[26].push_back(119);
        tempPatches[26].push_back(120);
        tempPatches[26].push_back(130);
        tempPatches[26].push_back(131);

        tempPatches[27].push_back(88);
        tempPatches[27].push_back(90);
        tempPatches[27].push_back(98);
        tempPatches[27].push_back(99);
        tempPatches[27].push_back(106);
        tempPatches[27].push_back(107);

        tempPatches[28].push_back(89);
        tempPatches[28].push_back(85);
        tempPatches[28].push_back(86);
        tempPatches[28].push_back(84);

        tempPatches[29].push_back(140);
        tempPatches[29].push_back(132);
        tempPatches[29].push_back(133);
        tempPatches[29].push_back(128);
        tempPatches[29].push_back(129);
        tempPatches[29].push_back(116);
        tempPatches[29].push_back(118);

        tempPatches[30].push_back(97);
        tempPatches[30].push_back(96);
        tempPatches[30].push_back(104);
        tempPatches[30].push_back(105);
        tempPatches[30].push_back(112);
        tempPatches[30].push_back(117);



        for (int i=0;i<NTMARK;i++)
        {
            float color[3];
            if (i<NTMARK/3)
            {
                color[0] = (float)(i)/((float)(NTMARK)/3.f);
                color[1] = 0;
                color[2] = 0;
            }
            if (i >= NTMARK/3 && i<2*NTMARK/3)
            {
                color[0] = 1;
                color[1] = (float)(i-NTMARK/3)/((float)(NTMARK)/3.f);
                color[2] = 0;
            }
            if (i>=2*NTMARK/3)
            {
                color[0] = 0;
                color[1] = 1;
                color[2] = (float)(i-2*NTMARK/3)/((float)(NTMARK)/3.f);
            }
            color[0] /= 2;
            color[1] /= 2;
            color[2] /= 2;
            setPatchColor(i, color);
        }

        currentView = 4;
        nextView = currentView;
        currentLoc = cameraViews[currentView];
        steps = 0;
        totalSteps = 50;

        fMin = 0.f;
        fMax = 50.f;
    }
    Q3DCameraWidget::~Q3DCameraWidget()
    {

    }
    void Q3DCameraWidget::timedUpdate()
    {
        updateGL();
    }
    void Q3DCameraWidget::updateData(float* dataa)
    {
        memcpy(&fscTemps[0], dataa, 60*sizeof(float));

        if (tempPatches.size() != 31 || !initFinished)
            return;

        for (int i=0;i<59;i++)
        {
//            cout << i << " " << fscTemps[i] << endl;
            float ratio = (fscTemps[i+1] - fMin)/(fMax - fMin);
 //           cout  << fscTemps[i+1] << " " << i << endl;
            float color[3];
            if (ratio > ss[4])
            {
                color[0] = tooHighValueCoulour[0];
                color[1] = tooHighValueCoulour[1];
                color[2] = tooHighValueCoulour[2];
            }
            else
            {
                if (ratio < ss[0])
                {
                    color[0] = tooLowValueCoulour[0];
                    color[1] = tooLowValueCoulour[1];
                    color[2] = tooLowValueCoulour[2];
                }
                else
                {
 //                   cout << "Calculating the actual value" << endl;
                    int index = 0;
                    while (index < 5 && ss[index] < ratio)
                        index ++;
                    index--;
                    float ratio2 = (ratio - ss[index])/(ss[index+1] - ss[index]);
                    float ratio3 = 1.f - ratio2;
                    color[0] = rr[index]*ratio3 + rr[index+1]*ratio2;
                    color[1] = gg[index]*ratio3 + gg[index+1]*ratio2;
                    color[2] = bb[index]*ratio3 + bb[index+1]*ratio2;
                }
            }
            if (i < 31)
            for (unsigned int j=0;j<tempPatches[i].size(); j++)
                setPatchColor(tempPatches[i][j], color);
            else
            {
                int ii = i-31;
                for (;ii<28;ii++)
                {
                    spheresRadius[ii] = 0.05*ratio + 0.01;
                    spheresColors[ii][0] = color[0];
                    spheresColors[ii][1] = color[1];
                    spheresColors[ii][2] = color[2];
                }

            }
        }


        if (!initFinished)
            return;
        UpdateText();
        emit dataHasChanged();
  //      timer.start();
 //       updateGL();

    }
    void Q3DCameraWidget::mousePressEvent(QMouseEvent* cEvent)
    {
        if (cEvent->pos().x() > width()-(width()/50.f))
        {
            toggleInterfaceDisplay();
            return;
        }
        int face = PixelAtPosition(cEvent->pos());
         if (face != -1) {
             fWhite = face;
             if (face < 1440)
                 fWhitePatch = pixelsPatch[fWhite];
             else
                 fWhitePatch = -1;
//             cout << "Patch Value: " << fWhitePatch << " fWhite: " << fWhite << endl;

             emit signalCurrentPixel(face);
             }
         else
         {
             fWhite = -1;
             fWhitePatch = -1;
         }
         UpdateText();
         updateGL();
    }
    void Q3DCameraWidget::mouseDoubleClickEvent(QMouseEvent *cEvent)
    {
        int face = PixelAtPosition(cEvent->pos());
         if (face != -1 && face < 1440) {
             highlightPatches.push_back(pixelsPatch[face]);
             updateGL();
             return;
//             fWhitePatch = pixelsPatch[fWhite];
         }
        int dir = 0;
        int xx = cEvent->pos().x();
        int yx = cEvent->pos().y();
        if (xx > width()/3) dir++;
        if (xx > 2*width()/3) dir++;
        if (yx > height()/3) dir+=3;
        if (yx > 2*height()/3) dir+=3;

        if (steps)
            return;

        nextView = dir;

        if (nextView == currentView)
            return;
        steps = totalSteps;
        timer.start();
    }
    int Q3DCameraWidget::PixelAtPosition(const QPoint &cPos)
    {
        const int MaxSize = 512;
        GLuint buffer[MaxSize];
        GLint viewport[4];

        makeCurrent();

        glGetIntegerv(GL_VIEWPORT, viewport);
        glSelectBuffer(MaxSize, buffer);
        glRenderMode(GL_SELECT);

        glInitNames();
        glPushName(0);

        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
//cout << "Viewport: " << viewport[0] << " " << viewport[1] << " " << viewport[2] << " " << viewport[3] << endl;
        gluPickMatrix(cPos.x(), viewport[3] - cPos.y(), 1, 1, viewport);

        GLfloat windowRatio = (float)viewport[2]/(float)viewport[3];
        gluPerspective(40.f, windowRatio, 1, 10);

        glMatrixMode(GL_MODELVIEW);
        isPicking = true;
        paintGL();
        isPicking = false;
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();

        //for some reason that I cannot understand, the push/pop matrix doesn't do the trick here... bizarre
        //ok, so re-do the resizeGL thing.
        resizeGL(width(), height());

        int hits = glRenderMode(GL_RENDER);
        if (!hits)
            return -1;
//        else
 //           cout << "There are " << hits << " hits..." << endl;
//        for (int i=0;i<MaxSize;i++)
//            cout << buffer[i] << " ";
 //       cout << endl;

        if (buffer[3] < 1440+28)
            return buffer[3];
        else
            return -1;
    }
    void Q3DCameraWidget::paintGL()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();

        glTranslatef(0,-0.315, -3);
//        glScalef(1.5, 1.5, 1.5);

        float speed = 0.5f + 0.5f*cos(M_PI*((float)steps/(float)(totalSteps)));


        if (currentView != nextView)
        {
            float targetRotX = cameraViews[nextView].rotX;
            float targetRotY = cameraViews[nextView].rotY;
            if (fabs(targetRotX - 315) < 0.01f && cameraViews[currentView].rotX == 0)
                targetRotX -= 360;
            if (fabs(targetRotX) < 0.01f && cameraViews[currentView].rotX == 315)
                targetRotX += 360;

            if (fabs(targetRotY - 315) < 0.01f && cameraViews[currentView].rotY == 0)
                targetRotY -= 360;
            if (fabs(targetRotY) < 0.01f && cameraViews[currentView].rotY == 315)
                targetRotY += 360;
            currentLoc.rotX = cameraViews[currentView].rotX + speed*(targetRotX - cameraViews[currentView].rotX);
            currentLoc.rotY = cameraViews[currentView].rotY + speed*(targetRotY - cameraViews[currentView].rotY);
            for (int i=0;i<3;i++)
                currentLoc.position[i] = cameraViews[currentView].position[i] + speed*(cameraViews[nextView].position[i] - cameraViews[currentView].position[i]);
            steps--;
            if (!steps)//fabs(currentLoc.rotX - cameraViews[nextView].rotX) <0.01)
            {
                currentLoc = cameraViews[nextView];
 //               currentLoc.rotX = cameraViews[nextView].rotX;
 //               currentLoc.rotY = cameraViews[nextView].rotY;
 //               for (int i=0;i<3;i++)
 //               currentLoc.position[i] = cameraViews[nextView].position[i];
                currentView = nextView;
                timer.stop();
            }
        }
        else
        {
            timer.stop();
        }
        glTranslatef(currentLoc.position[0], currentLoc.position[1], currentLoc.position[2]);
        glRotatef(currentLoc.rotX, 1,0,0);
        glRotatef(currentLoc.rotY, 0,1,0);

       glTranslatef(0,0.315,0);
       glRotatef(cameraRotation, 0,0,1);
       glTranslatef(0,-0.315,0);
 //       rotY +=0.1;
 //       glRotatef(rotY, 0,1,0);
 //       glRotatef(rotX, 1,0,0);
//        glRotatef(90, 1,0,0);
        drawCamera(true);
        glTranslatef(0,0,0.01);
        drawPatches();
        if (fWhite != -1 && fWhite < 1440)
        {
            glTranslatef(0,0,0.01);
            glColor3f(1.f, 0.f, 0.f);
            drawHexagon(fWhite, false);
            glTranslatef(0,0,-0.01);
       }
        glTranslatef(0,0,0.01);
        glColor3f(1.0f, 0.5f, 0.0f);
        glBegin(GL_LINES);
        for (auto it=highlightPatches.begin(); it!=highlightPatches.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();

        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glTranslatef(0,0.315, 0);
        glRotatef(180,1,0,0);
        drawSpheres();
        drawCameraBody();
        if (fWhite < 1500 && fWhite >= 1440)
        {
 //           cout << "Drawing wireframe sphere " << fWhite << endl;
            glPushMatrix();
            GLfloat red[4] = {0, 0, 0, 1};
            red[0] = 1.f - spheresColors[fWhite-1440][0];
            red[1] = 1.f - spheresColors[fWhite-1440][1];
            red[2] = 1.f - spheresColors[fWhite-1440][2];
            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
            glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
 //           glColor3fv(spheresColors[i].data);
            glTranslatef(spheresLocation[fWhite-1440][0], spheresLocation[fWhite-1440][1], spheresLocation[fWhite-1440][2]);
            gluSphere(gluNewQuadric(), 0.11f, 15, 15);
            glPopMatrix();
            glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
        }


        glDisable(GL_LIGHTING);

        if (isPicking)
            return;

        BasicGlCamera::resizeGL(width(), height());
        glDisable(GL_DEPTH_TEST);
        DrawCameraText();
        DrawScale();
        glEnable(GL_DEPTH_TEST);
        resizeGL(width(), height());

        initFinished = true;

    }
    void Q3DCameraWidget::UpdateText()
    {
        if (fWhitePatch != -1)
        {
            ostringstream str;
            str << "Patch " << fWhitePatch << " Temperature: ";
            int patchIndice = -1;
            unsigned int i=0;
            for (auto it = tempPatches.begin(); it != tempPatches.end(); it++)
            {
                for (auto jt = it->begin(); jt != it->end(); jt++)
                    if (*jt == fWhitePatch)
                    {
                        patchIndice = i;
                        break;
                    }
                if (patchIndice != -1)
                    break;
                i++;
            }
            if (i==tempPatches.size())
            {
                dataText = "Error, patch couldn't be found in patch list";
            }
            else
            {
                str << fscTemps[i+1] << " degrees";
                dataText = str.str();
            }
            return;
        }
        if (fWhite >= 1440 && fWhite < 1500)
        {
            ostringstream str;
            int whi = fWhite - 1440;
            switch (whi)
            {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
               str << "Crate sensor #" << whi;
                break;
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
            case 13:
            case 14:
            case 15:
                str << "Power supply (crate) #" << whi-8;
                break;
            case 16:
            case 17:
            case 18:
            case 19:
                str << "Power supply (Aux) #" << whi - 16;
                break;
            case 20:
            case 21:
            case 22:
            case 23:
                str << "Back panel #" << whi - 20;
                break;
            case 24:
            case 25:
            case 26:
            case 27:
                str << "Switch box #" << whi - 24;
                break;
            default:
                str << "Something went wrong " << whi;
            }
            str << ": " << fscTemps[whi+32] << " degrees";
            dataText = str.str();
            return;
        }

        dataText = "";
    }
    void Q3DCameraWidget::drawSpheres()
    {
//        GLUquadric* quad = gluNewQuadric();
        for (int i=0;i<28;i++)
        {
            glPushMatrix();
            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, spheresColors[i].data);
            glLoadName(i + 1440);
 //           glColor3fv(spheresColors[i].data);
            glTranslatef(spheresLocation[i][0], spheresLocation[i][1], spheresLocation[i][2]);
            gluSphere(gluNewQuadric(), 0.1f, 10, 10);//spheresRadius[i], 10, 10);
            glPopMatrix();
        }
        glLoadName(1500);
        glPushAttrib(GL_LIGHTING_BIT);
        glDisable(GL_LIGHTING);
        glColor3f(0.6,0.6,0.6);
        glBegin(GL_LINE_LOOP);
        for (int i=0;i<4;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=4;i<8;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=8;i<12;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=12;i<16;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=16;i<18;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=18;i<20;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=20;i<24;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=24;i<26;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();
        glBegin(GL_LINE_LOOP);
        for (int i=26;i<28;i++)
            glVertex3fv(spheresLocation[i].data);
        glEnd();

        glPopAttrib();
    }

    void Q3DCameraWidget::drawCameraBody()
    {
        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

        GLfloat color[4] = {0.4f, 0.5f, 0.5f, 1.f};
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 1.0f);
        gluCylinder( gluNewQuadric(),
                        0.62,
                        0.62,
                        1.83,
                        30,
                        2 );
        glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );



    }
    void Q3DCameraWidget::drawCamera(bool alsoWire)
    {
        glColor3f(0.5,0.5,0.5);
        glLineWidth(1.0);
        for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
        {
            glColor3fv(pixelsColor[i]);
            glLoadName(i);
            drawHexagon(i,true);
        }
        if (!alsoWire)
            return;
        glTranslatef(0,0,0.01);
        glColor3f(0.0f,0.0f,0.0f);
        for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
        {
            drawHexagon(i, false);
        }
//        glLoadName(1440);
    }
    void Q3DCameraWidget::initializeGL()
    {
        qglClearColor(QColor(25,25,38));

        glShadeModel(GL_SMOOTH);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glDisable(GL_CULL_FACE);
//        glCullFace(GL_FRONT);

        glEnable(GL_LINE_SMOOTH);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    }
    void Q3DCameraWidget::resizeGL(int cWidth, int cHeight)
    {
        glViewport(0,0,cWidth, cHeight);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        GLfloat windowRatio = (float)cWidth/(float)cHeight;
        if (windowRatio < 1)
        {
//            windowRatio = 1.0f/windowRatio;
            gluPerspective(40.f, windowRatio, 1, 10);
//            gluOrtho2D(-viewSize, viewSize, -viewSize*windowRatio, viewSize*windowRatio);
            pixelSize = 2*viewSize/(float)cWidth;
            shownSizex = 2*viewSize;
            shownSizey = 2*viewSize*windowRatio;
        }
        else
        {
            gluPerspective(40.f, windowRatio, 1, 10);
//            gluOrtho2D(-viewSize*windowRatio, viewSize*windowRatio, -viewSize, viewSize);
            pixelSize = 2*viewSize/(float)cHeight;
            shownSizex = 2*viewSize*windowRatio;
            shownSizey = 2*viewSize;
        }
        glMatrixMode(GL_MODELVIEW);
    }
