#include "pageflipmath_p.h"
 #include <QtCore/qmath.h>
 #include <string.h>
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
 #endif
 PageFlipMath::PageFlipMath()
 {
     m_showPageReverse = false;
     m_startCorner = BottomRight;
     memset(vertices, 0, sizeof(vertices));
     memset(pageCount, 0, sizeof(pageCount));
 }
 PageFlipMath::~PageFlipMath()
 {
 }
 void PageFlipMath::drawPage(int page) const
 {
     if (page < 0 || page >= 4 || pageCount[page] == 0)
     return;
     glDrawArrays(GL_TRIANGLE_FAN, page * 5, pageCount[page]);
 }
 void PageFlipMath::drawOutline(int page) const
 {
     if (page < 0 || page >= 4 || pageCount[page] == 0)
     return;
     glDrawArrays(GL_LINE_LOOP, page * 5, pageCount[page]);
 }
 void PageFlipMath::compute(qreal t)
 {
     int page, vertex;
     
     if (m_startCorner < VerticalBottomRight)
         flip(m_pageRect.width() - 1, m_pageRect.height() - 1, t);
     else
         flip(m_pageRect.height() - 1, m_pageRect.width() - 1, t);
     
     switch (m_startCorner) {
     case BottomRight: break;
     case TopRight:
         for (page = 0; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 vertices[page][vertex][1]
                     = m_pageRect.height() - 1 - vertices[page][vertex][1];
             vertices[page][vertex][3]
                     = 1.0f - vertices[page][vertex][3];
             }
         }
         break;
     case BottomLeft:
         for (page = 0; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 vertices[page][vertex][0]
                     = m_pageRect.width() - 1 - vertices[page][vertex][0];
                 vertices[page][vertex][0] -= m_pageRect.width();
             vertices[page][vertex][2]
                     = 1.0f - vertices[page][vertex][2];
             }
         }
         break;
     case TopLeft:
         for (page = 0; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 vertices[page][vertex][0]
                     = m_pageRect.width() - 1 - vertices[page][vertex][0];
                 vertices[page][vertex][0] -= m_pageRect.width();
                 vertices[page][vertex][1]
                     = m_pageRect.height() - 1 - vertices[page][vertex][1];
             vertices[page][vertex][2]
                     = 1.0f - vertices[page][vertex][2];
             vertices[page][vertex][3]
                     = 1.0f - vertices[page][vertex][3];
             }
         }
         break;
     case BottomLeftOnePage:
         for (page = 1; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 vertices[page][vertex][0]
                     = m_pageRect.width() - 1 - vertices[page][vertex][0];
             vertices[page][vertex][2]
                     = 1.0f - vertices[page][vertex][2];
             }
         }
         break;
     case TopLeftOnePage:
         for (page = 1; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 vertices[page][vertex][0]
                     = m_pageRect.width() - 1 - vertices[page][vertex][0];
                 vertices[page][vertex][1]
                     = m_pageRect.height() - 1 - vertices[page][vertex][1];
             vertices[page][vertex][2]
                     = 1.0f - vertices[page][vertex][2];
             vertices[page][vertex][3]
                     = 1.0f - vertices[page][vertex][3];
             }
         }
         break;
     case VerticalBottomRight:
         for (page = 0; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
                 vertices[page][vertex][0]
                     = m_pageRect.width() - 1 - vertices[page][vertex][0];
                 vertices[page][vertex][1]
                     = m_pageRect.height() - 1 - vertices[page][vertex][1];
                 qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
             vertices[page][vertex][2]
                     = 1.0f - vertices[page][vertex][2];
             vertices[page][vertex][3]
                     = 1.0f - vertices[page][vertex][3];
             }
         }
         break;
     case VerticalTopRight:
         for (page = 0; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
                 vertices[page][vertex][0]
                     = m_pageRect.width() - 1 - vertices[page][vertex][0];
                 qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
             vertices[page][vertex][2]
                     = 1.0f - vertices[page][vertex][2];
             }
         }
         break;
     case VerticalBottomLeft:
         for (page = 0; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
                 vertices[page][vertex][1]
                     = m_pageRect.height() - 1 - vertices[page][vertex][1];
                 qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
             vertices[page][vertex][3]
                     = 1.0f - vertices[page][vertex][3];
             }
         }
         break;
     case VerticalTopLeft:
         for (page = 0; page < 4; ++page) {
         for (vertex = 0; vertex < pageCount[page]; ++vertex) {
                 qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
                 qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
             }
         }
         break;
     }
     
     for (page = 0; page < 4; ++page) {
     for (vertex = 0; vertex < pageCount[page]; ++vertex) {
         vertices[page][vertex][0] += m_pageRect.x();
         vertices[page][vertex][1]
         = m_pageRect.y() +
           (m_pageRect.height() - 1 - vertices[page][vertex][1]);
     }
     }
     
     if (m_showPageReverse) {
         if (m_startCorner < VerticalBottomRight) {
             for (int vertex = 0; vertex < pageCount[2]; ++vertex)
                 vertices[2][vertex][2] = 1.0f - vertices[2][vertex][2];
         } else {
             for (int vertex = 0; vertex < pageCount[2]; ++vertex)
                 vertices[2][vertex][3] = 1.0f - vertices[2][vertex][3];
         }
     }
 }
 
 
 
 
 
 void PageFlipMath::flip(qreal pageWidth, qreal pageHeight, qreal t)
 {
     
     if (t <= 0.0f) {
     
     
     pageCount[0] = 4;
     pageCount[1] = 4;
     pageCount[2] = 0;
     pageCount[3] = 0;
     vertices[0][0][0] = -pageWidth; 
     vertices[0][0][1] = 0.0f;
     vertices[0][0][2] = 0.0f; 
     vertices[0][0][3] = 0.0f;
     vertices[0][0][4] = 0.0f; 
     vertices[0][1][0] = 0.0f; 
     vertices[0][1][1] = 0.0f;
     vertices[0][1][2] = 1.0f;
     vertices[0][1][3] = 0.0f;
     vertices[0][1][4] = 1.0f; 
     vertices[0][2][0] = 0.0f; 
     vertices[0][2][1] = pageHeight;
     vertices[0][2][2] = 1.0f;
     vertices[0][2][3] = 1.0f;
     vertices[0][2][4] = 1.0f;
     vertices[0][3][0] = -pageWidth; 
     vertices[0][3][1] = pageHeight;
     vertices[0][3][2] = 0.0f;
     vertices[0][3][3] = 1.0f;
     vertices[0][3][4] = 0.0f;
     vertices[1][0][0] = 0.0f; 
     vertices[1][0][1] = 0.0f;
     vertices[1][0][2] = 0.0f; 
     vertices[1][0][3] = 0.0f;
     vertices[1][0][4] = 1.0f; 
     vertices[1][1][0] = pageWidth; 
     vertices[1][1][1] = 0.0f;
     vertices[1][1][2] = 1.0f;
     vertices[1][1][3] = 0.0f;
         vertices[1][1][4] = 0.0f;
     vertices[1][2][0] = pageWidth; 
     vertices[1][2][1] = pageHeight;
     vertices[1][2][2] = 1.0f;
     vertices[1][2][3] = 1.0f;
     vertices[1][2][4] = 0.0f;
     vertices[1][3][0] = 0.0f; 
     vertices[1][3][1] = pageHeight;
     vertices[1][3][2] = 0.0f;
     vertices[1][3][3] = 1.0f;
     vertices[1][3][4] = 1.0f;
     return;
     } else if (t >= 1.0f) {
     
     
     pageCount[0] = 0;
     pageCount[1] = 0;
     pageCount[2] = 4;
     pageCount[3] = 4;
     vertices[2][0][0] = -pageWidth; 
     vertices[2][0][1] = 0.0f;
     vertices[2][0][2] = 0.0f; 
     vertices[2][0][3] = 0.0f;
     vertices[2][0][4] = 0.0f; 
     vertices[2][1][0] = 0.0f; 
     vertices[2][1][1] = 0.0f;
     vertices[2][1][2] = 1.0f;
     vertices[2][1][3] = 0.0f;
     vertices[2][1][4] = 1.0f; 
     vertices[2][2][0] = 0.0f; 
     vertices[2][2][1] = pageHeight;
     vertices[2][2][2] = 1.0f;
     vertices[2][2][3] = 1.0f;
     vertices[2][2][4] = 1.0f;
     vertices[2][3][0] = -pageWidth; 
     vertices[2][3][1] = pageHeight;
     vertices[2][3][2] = 0.0f;
     vertices[2][3][3] = 1.0f;
     vertices[2][3][4] = 0.0f;
     vertices[3][0][0] = 0.0f; 
     vertices[3][0][1] = 0.0f;
     vertices[3][0][2] = 0.0f; 
     vertices[3][0][3] = 0.0f;
     vertices[3][0][4] = 1.0f; 
     vertices[3][1][0] = pageWidth; 
     vertices[3][1][1] = 0.0f;
     vertices[3][1][2] = 1.0f;
     vertices[3][1][3] = 0.0f;
     vertices[3][1][4] = 0.0f;
     vertices[3][2][0] = pageWidth; 
     vertices[3][2][1] = pageHeight;
     vertices[3][2][2] = 1.0f;
     vertices[3][2][3] = 1.0f;
     vertices[3][2][4] = 0.0f;
     vertices[3][3][0] = 0.0f; 
     vertices[3][3][1] = pageHeight;
     vertices[3][3][2] = 0.0f;
     vertices[3][3][3] = 1.0f;
     vertices[3][3][4] = 1.0f;
     return;
     }
     
     pageCount[0] = 4;
     vertices[0][0][0] = -pageWidth; 
     vertices[0][0][1] = 0.0f;
     vertices[0][0][2] = 0.0f;  
     vertices[0][0][3] = 0.0f;
     vertices[0][0][4] = 0.0f;  
     vertices[0][1][0] = 0.0f;  
     vertices[0][1][1] = 0.0f;
     vertices[0][1][2] = 1.0f;
     vertices[0][1][3] = 0.0f;
     vertices[0][1][4] = 1.0f;  
     vertices[0][2][0] = 0.0f;  
     vertices[0][2][1] = pageHeight;
     vertices[0][2][2] = 1.0f;
     vertices[0][2][3] = 1.0f;
     vertices[0][2][4] = 1.0f;
     vertices[0][3][0] = -pageWidth; 
     vertices[0][3][1] = pageHeight;
     vertices[0][3][2] = 0.0f;
     vertices[0][3][3] = 1.0f;
     vertices[0][3][4] = 0.0f;
     
     
     
     qreal angle = (M_PI / 4.0f) * (1.0f + t);
     
     qreal cosAngle = qCos(angle);
     qreal sinAngle = qSin(angle);
     qreal cosAngle2 = qCos(angle * 2.0f);
     qreal sinAngle2 = qSin(angle * 2.0f);
     
     
     qreal refx = pageWidth * (1.0f - t);
     qreal refy = 0.0f;
     
     qreal d = pageWidth - refx;
     
     
     
     
     qreal k = (pageHeight * cosAngle) / sinAngle;
     if (k >= d) {
     
     
     qreal intx = pageWidth;
     qreal inty = refy + (d * sinAngle) / cosAngle;
     
     qreal oppx = refx + d * cosAngle2;
     qreal oppy = refy + d * sinAngle2;
     
     qreal texa = 1.0f - (d * sinAngle) / (pageHeight * cosAngle);
     qreal texb = d / pageWidth;
     vertices[2][0][0] = intx;
     vertices[2][0][1] = inty;
     vertices[2][0][2] = 0.0f;
     vertices[2][0][3] = 1.0f - texa;
     vertices[2][0][4] = 1.0f;
     vertices[2][1][0] = oppx;
     vertices[2][1][1] = oppy;
     vertices[2][1][2] = 0.0f;
     vertices[2][1][3] = 0.0f;
     vertices[2][1][4] = 1.0f - texb;
     vertices[2][2][0] = refx;
     vertices[2][2][1] = refy;
     vertices[2][2][2] = texb;
     vertices[2][2][3] = 0.0f;
     vertices[2][2][4] = 1.0f;
     pageCount[2] = 3;
     
     vertices[3][0][0] = intx;
     vertices[3][0][1] = inty;
     vertices[3][0][2] = 1.0f;
     vertices[3][0][3] = 1.0f - texa;
     vertices[3][0][4] = 1.0f;
     vertices[3][1][0] = refx;
     vertices[3][1][1] = refy;
     vertices[3][1][2] = 1.0f - texb;
     vertices[3][1][3] = 0.0f;
     vertices[3][1][4] = 1.0f;
     vertices[3][2][0] = pageWidth;
     vertices[3][2][1] = 0.0f;
     vertices[3][2][2] = 1.0f;
     vertices[3][2][3] = 0.0f;
     vertices[3][2][4] = 1.0f - texb;
     pageCount[3] = 3;
     
     vertices[1][0][0] = 0.0f;
     vertices[1][0][1] = 0.0f;
     vertices[1][0][2] = 0.0f;
     vertices[1][0][3] = 0.0f;
     vertices[1][0][4] = 1.0f;
     vertices[1][1][0] = pageWidth - d;
     vertices[1][1][1] = 0.0f;
     vertices[1][1][2] = 1.0f - texb;
     vertices[1][1][3] = 0.0f;
     vertices[1][1][4] = texb;
     vertices[1][2][0] = intx;
     vertices[1][2][1] = inty;
     vertices[1][2][2] = 1.0f;
     vertices[1][2][3] = 1.0f - texa;
     vertices[1][2][4] = 0.0f;
     vertices[1][3][0] = pageWidth;
     vertices[1][3][1] = pageHeight;
     vertices[1][3][2] = 1.0f;
     vertices[1][3][3] = 1.0f;
     vertices[1][3][4] = 0.0f;
     vertices[1][4][0] = 0.0f;
     vertices[1][4][1] = pageHeight;
     vertices[1][4][2] = 0.0f;
     vertices[1][4][3] = 1.0f;
     vertices[1][4][4] = 1.0f;
     pageCount[1] = 5;
     } else {
     
     
     qreal intx = refx + (pageHeight * cosAngle) / sinAngle;
     qreal inty = pageHeight;
     
     qreal e = pageWidth - intx;
     
     qreal opprefx = refx + d * cosAngle2;
     qreal opprefy = refy + d * sinAngle2;
     qreal oppintx = intx + e * cosAngle2;
     qreal oppinty = inty + e * sinAngle2;
     
     qreal texa = e / pageWidth;
     qreal texb = d / pageWidth;
     vertices[2][0][0] = intx;
     vertices[2][0][1] = inty;
     vertices[2][0][2] = texa;
     vertices[2][0][3] = 1.0f;
     vertices[2][0][4] = 1.0f;
     vertices[2][1][0] = oppintx;
     vertices[2][1][1] = oppinty;
     vertices[2][1][2] = 0.0f;
     vertices[2][1][3] = 1.0f;
     vertices[2][1][4] = 1.0f - texa;
     vertices[2][2][0] = opprefx;
     vertices[2][2][1] = opprefy;
     vertices[2][2][2] = 0.0f;
     vertices[2][2][3] = 0.0f;
     vertices[2][2][4] = 1.0f - texb;
     vertices[2][3][0] = refx;
     vertices[2][3][1] = refy;
     vertices[2][3][2] = texb;
     vertices[2][3][3] = 0.0f;
     vertices[2][3][4] = 1.0f;
     pageCount[2] = 4;
     
     vertices[3][0][0] = intx;
     vertices[3][0][1] = inty;
     vertices[3][0][2] = 1.0f - texa;
     vertices[3][0][3] = 1.0f;
     vertices[3][0][4] = 1.0f;
     vertices[3][1][0] = refx;
     vertices[3][1][1] = refy;
     vertices[3][1][2] = 1.0f - texb;
     vertices[3][1][3] = 0.0f;
     vertices[3][1][4] = 1.0f;
     vertices[3][2][0] = pageWidth;
     vertices[3][2][1] = 0.0f;
     vertices[3][2][2] = 1.0f;
     vertices[3][2][3] = 0.0f;
     vertices[3][2][4] = 1.0f - texb;
     vertices[3][3][0] = pageWidth;
     vertices[3][3][1] = pageHeight;
     vertices[3][3][2] = 1.0f;
     vertices[3][3][3] = 1.0f;
     vertices[3][3][4] = 1.0f - texa;
     pageCount[3] = 4;
     
     vertices[1][0][0] = 0.0f;
     vertices[1][0][1] = 0.0f;
     vertices[1][0][2] = 0.0f;
     vertices[1][0][3] = 0.0f;
     vertices[1][0][4] = 1.0f;
     vertices[1][1][0] = pageWidth - d;
     vertices[1][1][1] = 0.0f;
     vertices[1][1][2] = 1.0f - texb;
     vertices[1][1][3] = 0.0f;
     vertices[1][1][4] = texb;
     vertices[1][2][0] = pageWidth - e;
     vertices[1][2][1] = pageHeight;
     vertices[1][2][2] = 1.0f - texa;
     vertices[1][2][3] = 1.0f;
     vertices[1][2][4] = texa;
     vertices[1][3][0] = 0.0f;
     vertices[1][3][1] = pageHeight;
     vertices[1][3][2] = 0.0f;
     vertices[1][3][3] = 1.0f;
     vertices[1][3][4] = 1.0f;
     pageCount[1] = 4;
     }
 }