#include "parser.h"
#include <QFile>
#include <QTextStream>
#include <Common/constants.h>
#include <Model/menu.h>

Parser::Parser()
{

}

void Parser::parse(Information *interfaz, QString path)
{
    QString source = getTemplateSource(Constants::Parser::QmlTemplates::information);
    source = setSizeProperties(source, interfaz);
    source = setBackGroundProperties(source, interfaz);

    bool hasIcons = interfaz->getHasIcons();
    int numberOfElements = interfaz->getNumberOfElements();
    int rows = ((Information *)interfaz)->getNumberOfRows();
    int cols = ((Information *)interfaz)->getNumberOfCols();

    QVector<Card*> *cards = interfaz->getCards();

    QString iconView;
    if(hasIcons)
    {
        iconView = getTemplateSource(Constants::Parser::QmlTemplates::informationIcon);
    }

    QString elements;
    for(int i=0; i<numberOfElements; i++)
    {
        QString element = getTemplateSource(Constants::Parser::QmlTemplates::informationElement);
        int cardRows = ((Information *)interfaz)->getCardRows();
        int cardCols = ((Information *)interfaz)->getCardCols();

        element.replace(CARD_INDEX, QString("card%1").arg(i));
        element.replace(CARD_TITLE, cards->at(i)->getTitle());
        element.replace(Constants::Parser::InformationView::rowElements, QString::number(cardRows));
        element.replace(Constants::Parser::InformationView::colElements, QString::number(cardCols));

        QString icon;
        if(hasIcons) icon = cards->at(i)->getIconImage();
        element.replace(CARD_ICON, icon);

        QString elementProperties = formInformationElement(cards->at(i));
        element.replace(CARD_PROPERTY, elementProperties);


        elements.append(element);
    }
    QString viewElements = formInformationViewElement(interfaz);

    source.replace(CARD_VIEW_PROPERTY, viewElements);
    source.replace(CARD_ICON_VIEW, iconView);
    source.replace(LIST_ELEMENT, elements);

    saveResult(source, path);

}


QString Parser::formInformationElement(Card *card)
{
    QString elementProperties;
    int numberOfProperties = card->getNumberOfProperties();

    for(int j=0; j < numberOfProperties; j++)
    {
        QStringList newProperty = card->getProperty(j);
        QString property = formProperty(j,newProperty);
        elementProperties.append(property);
    }

    return elementProperties;
}

QString Parser::formInformationViewElement(Information *interfaz)
{
    int rows  = interfaz->getCardRows();
    int cols = interfaz->getCardCols();
    bool hasIcon = interfaz->getHasIcons();   
    int position = 0;

    QString viewElements;
    for(int i= 0; i <rows; i++)
    {

        for(int j = 0; j <cols; j++)
        {           
            QString element = getTemplateSource(Constants::Parser::QmlTemplates::informationElementView);
            if(hasIcon)
                element.replace(Constants::Parser::InformationView::iconResize, " - icon.width");
             else
                element.replace(Constants::Parser::InformationView::iconResize, "");

            if(i == 0 || j == 0)
            {
                element.replace(LEFT_MARGIN, QString("10"));

                //First icon special position
                if(i == 0 && j == 0)
                {
                    if(hasIcon)
                    {
                        element.replace(LEFT_POSITION, IMAGE_ID);
                        element.replace(RELATIVE_POSITION, QString("right"));
                    }
                    else
                    {
                        element.replace(LEFT_POSITION, PARENT);
                        element.replace(RELATIVE_POSITION, QString("left"));
                    }
                }

                //First line
                if(i == 0)
                {
                    element.replace(TOP_POSITION, SEPARATOR);
                    element.replace(LEFT_POSITION, QString("rect%1").arg(position - 1));
                    element.replace(RELATIVE_POSITION, QString("right"));
                }

                //First Column
                if(j == 0)
                {
                    element.replace(TOP_POSITION, QString("rect%1").arg(position - cols));
                    element.replace(LEFT_MARGIN, QString("10"));

                    if(hasIcon)
                    {
                        element.replace(LEFT_POSITION, IMAGE_ID);
                        element.replace(RELATIVE_POSITION, QString("right"));
                    }
                    else
                    {
                        element.replace(LEFT_POSITION, PARENT);
                        element.replace(RELATIVE_POSITION, QString("left"));
                    }
                }
            }
            //Common elements
            else
            {
                element.replace(TOP_POSITION, QString("rect%1").arg(position - cols));
                element.replace(LEFT_MARGIN, QString("0"));
                element.replace(LEFT_POSITION, QString("rect%1").arg(position - cols));
                element.replace(RELATIVE_POSITION, QString("left"));
                element.replace(LEFT_MARGIN, QString::number(0));
            }

            QString propertyRect = QString("rect%1").arg(position);
            QString propertyViewIndex = QString("propertyView%1").arg(position);
            QString valueViewIndex = QString("valueView%1").arg(position);
            QString propertyIndex = QString("property%1").arg(position);
            QString valueIndex = QString("value%1").arg(position);

            element.replace(NUMBER_COLS, QString::number(cols));
            element.replace(NUMBER_ROWS, QString::number(rows));
            element.replace(PROPERTY_RECT, propertyRect);
            element.replace(PROPERTY_VIEW_INDEX, propertyViewIndex);
            element.replace(VALUE_VIEW_INDEX, valueViewIndex);
            element.replace(PROPERTY_INDEX, propertyIndex );
            element.replace(VALUE_INDEX, valueIndex );

            position ++;
            viewElements.append(element);
        }
    }

    return viewElements;
}

void Parser::parse(Ink *interfaz, QString path)
{
    QString source = getTemplateSource(Constants::Parser::QmlTemplates::ink);
    source = setSizeProperties(source, interfaz);

    int numberOfElements = interfaz->getNumberOfElements();
    int rows = interfaz->getNumberOfRows();
    int cols = interfaz->getNumberOfCols();
    source = inkTextOption(source, interfaz->getTextOption());

    if(rows < cols) source.replace(ORIENTATION, VERTICAL);
    else source.replace(ORIENTATION, HORIZONTAL);

    QString elements;
    for(int element = 0; element < numberOfElements; element ++)
    {
        QString inkElement = getTemplateSource(Constants::Parser::QmlTemplates::inkElement);
        QColor inkColor = interfaz->getColor(element);
        inkElement.replace(COLOR, inkColor.name());
        elements.append(inkElement);
    }

    source.replace(LIST_ELEMENT, elements);
    saveResult(source, path);


}

QString Parser::inkTextOption(QString source, InkTextOption textOption)
{
    QString text;
    QString color;
    switch (textOption) {
    case InkTextOption::Nothing:
        text = QString("progressBarElement.value*100 + '%'");
        color = QString("'transparent'");
        break;
    case InkTextOption::Number:
        text = QString("progressBarElement.value*100");
        color = QString("progressBarElement.value > 0.20 ? 'black' : 'red'");
        break;
    case InkTextOption::Percentage:
        text = QString("progressBarElement.value*100 + '%'");
        color = QString("progressBarElement.value > 0.20 ? 'black' : 'red'");
        break;
    default:
        break;
    }

    source.replace(Constants::Parser::InkView::textOption, text);
    source.replace(Constants::Parser::InkView::colorOption, color);

    return source;
}

QString Parser::formProperty(int propIndex, QStringList property)
{
    QString result = getTemplateSource(Constants::Parser::QmlTemplates::informationProperty);

    QString propertyIndex = QString("property%1").arg(propIndex);
    QString valueIndex = QString("value%1").arg(propIndex);

    result.replace(PROPERTY_INDEX, propertyIndex);
    result.replace(PROPERTY_NAME, property.takeFirst());
    result.replace(VALUE_INDEX, valueIndex);
    result.replace(PROPERTY_VALUE, property.takeFirst());

    return result;


}

void Parser::parse(Menu *interfaz, QString path)
{    
    QString source = getTemplateSource(Constants::Parser::QmlTemplates::menu);
    source = setSizeProperties(source, interfaz);
    source = setBackGroundProperties(source, interfaz);

    bool hasText = ((Menu *)interfaz)->isTitleEnabled();
    bool isAutomatic = ((Menu *)interfaz)->isAutomaticPosition();
    int numberOfIcons = interfaz->getNumberOfElements();

    QVector<Icon*> *icons = ((Menu *)interfaz)->getIcons();


    QString element = getTemplateSource(Constants::Parser::QmlTemplates::menuElement);
    QString sizeElement;
    QString sizeView;
    QString title;
    for(int i = 0; i< numberOfIcons; i++)
    {
        Icon *icon = icons->at(i);
        if(i != 0)
            element.append(getTemplateSource(Constants::Parser::QmlTemplates::menuElement));
        if(hasText)
        {
            title = icon->getTitle();
        }else{
            title = "";
        }
        if(!isAutomatic)
        {
            sizeElement = getTemplateSource(Constants::Parser::QmlTemplates::menuElementSize);
            sizeElement.replace(HEADER_MARGIN,QString::number (icon->getTopMargin()));
            sizeElement.replace(BOTTOM_MARGIN, QString::number(icon->getBottomMargin()));
            sizeElement.replace(LEFT_MARGIN,QString::number (icon->getLeftMargin()));
            sizeElement.replace(RIGHT_MARGIN, QString::number(icon->getRightMargin()));

            sizeView = getTemplateSource(Constants::Parser::QmlTemplates::menuElementSizeView);
        }else{
            sizeElement = "";
            sizeView = "";
        }
        element.replace(ICON_NAME, title);
        element.replace(IMAGE, icon->getPath());
        element.replace(CUSTOMIZE_SIZE, sizeElement);

    }

    source.replace(LIST_ELEMENT, element);
    source.replace(CUSTOMIZE_SIZE_VIEW, sizeView);    

    saveResult(source, path);



}

QString Parser::setSizeProperties(QString source, Interfaz *interfaz)
{
    source.replace(ROOT_WIDTH, QString::number(interfaz->getWidth()));
    source.replace(ROOT_HEIGHT,QString::number(interfaz->getHeight()));
    source.replace(NUMBER_COLS, QString::number(interfaz->getNumberOfCols()));
    source.replace(NUMBER_ROWS, QString::number(interfaz->getNumberOfRows()));

    return source;
}

QString Parser::setBackGroundProperties(QString source, Interfaz *interfaz)
{
    bool hasImageBackground = interfaz->getHasImageBackground();

    if(hasImageBackground)
    {
        QString imageSource = getTemplateSource(Constants::Parser::QmlTemplates::image);
        imageSource.replace(IMAGE, interfaz->getImageBackground());
        source.replace(BACKGROUND, imageSource);
    }
    else
    {
        QString colorSource = getTemplateSource(Constants::Parser::QmlTemplates::color);
        source.replace(BACKGROUND, colorSource);
        source.replace(COLOR, interfaz->getColorBackground().name());
    }

    return source;
}

void Parser::saveResult(QString result, QString path)
{
    QFile fileResult(path);
    if ( fileResult.open(QIODevice::WriteOnly) )
    {
        QTextStream stream( &fileResult );
        stream.setCodec("UTF-8");
        stream << result << endl;
    }
    fileResult.close();
}



QString Parser::getTemplateSource(QString path)
{
    QFile menuTemplate(path);

    if(!menuTemplate.open(QFile::ReadOnly)){        
        return QString("");
    }

    QTextStream in(&menuTemplate);
    QString templateSource = in.readAll();
    menuTemplate.close();

    return templateSource;
}
