/***************************************************************************
 *   Project TupiTube Desk                                                 *
 *   Project Contact: info@tupitube.com                                    *
 *   Project Website: http://www.tupitube.com                              * 
 *                                                                         *
 *   Developers:                                                           *
 *   2025:                                                                 *
 *    Utopian Lab Development Team                                         *
 *   2010:                                                                 *
 *    Gustav Gonzalez                                                      *
 *   ---                                                                   *
 *   KTooN's versions:                                                     *
 *   2006:                                                                 *
 *    David Cuadrado                                                       *
 *    Jorge Cuadrado                                                       *
 *   2003:                                                                 *
 *    Fernado Roldan                                                       *
 *    Simena Dinas                                                         *
 *                                                                         *
 *   License:                                                              *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "tpathhelper.h"

#include <QTransform>

TPathHelper::TPathHelper()
{
}

TPathHelper::~TPathHelper()
{
}

QPainterPath TPathHelper::toRect(const QPainterPath &p, const QRect &rect, float offset)
{
    QPainterPath path;
    
    QRectF br = p.boundingRect();
    QTransform t;
    
    float sx = 1, sy = 1;

    if (rect.width() < br.width())
        sx = static_cast<float>(rect.width()-offset) / static_cast<float>(br.width());

    if (rect.height() < br.height())
        sy = static_cast<float>(rect.height()-offset) / static_cast<float>(br.height());
    
    float factor = qMin(sx, sy);
    t.scale(factor, factor);
    path = t.map(p);
 
    t.reset();
    
    QPointF pos = path.boundingRect().topLeft();
    float tx = offset/2-pos.x(), ty = offset/2-pos.y();
    t.translate(tx, ty);

    return t.map(path);
}

QList<QPainterPath> TPathHelper::toRect(const QList<QPainterPath> &l, const QRect &rect, float offset)
{
    QList<QPainterPath> returnList;
    QRectF br;
    
    foreach (QPainterPath in, l)
             br = br | in.boundingRect().toRect();
    
    foreach (QPainterPath path, l) {
             QTransform t;
             float sx = 1, sy = 1;

             if (rect.width() < br.width())
                 sx = static_cast<float>(rect.width()-offset) / static_cast<float>(br.width());

             if (rect.height() < br.height())
                 sy = static_cast<float>(rect.height()-offset) / static_cast<float>(br.height());
        
             float factor = qMin(sx, sy);
             t.scale(factor, factor);
             path = t.map(path);
        
             t.reset();
        
             QPointF pos = path.boundingRect().topLeft();
             float tx = offset/2-pos.x();
             float ty = offset/2-pos.y();
             t.translate(tx, ty);
             returnList << t.map(path);
    }
    
    return returnList;
}

QPainterPath TPathHelper::buildPath(const QStringList &polygonsStr, QChar sep)
{
    // SQA: It doesn't work for curves
    QPainterPath path;
    
    foreach (QString polTmp, polygonsStr) {
        QStringList points = polTmp.trimmed().split(' ');
        
        QPolygonF polygon;
        
        foreach (QString p, points) {
                 bool valid = false;
                 double x = p.section(sep, 0, 0).toDouble(&valid);
                 double y = p.section(sep, 1, 1).toDouble(&valid);
            
                 if (valid)
                     polygon << QPointF(x, y);
        }
        
        path.addPolygon(polygon);
    }

    return path;
}

QPainterPath TPathHelper::buildPath(const QString &svgpath)
{
    Q_UNUSED(svgpath);

    #ifdef TUP_DEBUG
        qDebug() << "TPathHelper::buildPath() - Warning: method pending for implementation";
    #endif
    
    return QPainterPath();
}


QPainterPath TPathHelper::fromElements(const QList<QPainterPath::Element>& elements)
{
    QPainterPath shape;
    QVector<QPointF> curve;
    
    foreach (QPainterPath::Element e, elements) {
             switch(e.type) {
                    case QPainterPath::MoveToElement:
                    {
                         shape.moveTo(e.x, e.y);
                         break;
                    }
                    case QPainterPath::LineToElement:
                    {
                         shape.lineTo(e.x, e.y);
                         break;
                    }
                    case QPainterPath::CurveToDataElement:
                    {
                         curve << e;
                         if (curve.count() == 3)
                             shape.cubicTo(curve[0], curve[1], curve[2]);
                         break;
                    }
                    case QPainterPath::CurveToElement:
                    {
                         curve.clear();
                         curve << e;
                         break;
                    }
             }
    }

    return shape;
}

QList<QPainterPath> TPathHelper::toSubpaths(const QPainterPath &path)
{
    QList<QPainterPath> paths;
    QList<QPainterPath::Element> elements;
    
    for (int index = 0; index < path.elementCount(); index++) {
         QPainterPath::Element e = path.elementAt(index);
        
         if (e.type == QPainterPath::MoveToElement && !elements.isEmpty()) {
             QPainterPath path = TPathHelper::fromElements(elements);
             paths << path;
             elements.clear();
         }
        
         elements << e;
    }
    
    if (! elements.isEmpty()) {
        QPainterPath path = TPathHelper::fromElements(elements);
        paths << path;
        elements.clear();
    }
    
    return paths;
}
