/** *************************************************************************
                          labelnode.cpp  -  K Desktop Planetarium
                             -------------------
    begin                : 09/06/2016
    copyright            : (C) 2016 by Artem Fedoskin
    email                : afedoskin3@gmail.com
 ***************************************************************************/
/** *************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "skyobject.h"
#include "Options.h"

#include <QSGSimpleTextureNode>
#include <QQuickWindow>

#include "skymaplite.h"
#include "labelnode.h"

LabelNode::LabelNode(SkyObject *skyObject, LabelsItem::label_t type)
    : SkyNode(skyObject), m_name(skyObject->labelString()), m_textTexture(new QSGSimpleTextureNode), m_labelType(type),
      m_fontSize(0), m_zoomFont(false)
{
    initialize();
}

LabelNode::LabelNode(QString name, LabelsItem::label_t type)
    : m_name(name), m_textTexture(new QSGSimpleTextureNode), m_labelType(type), m_fontSize(0), m_zoomFont(false)
{
    initialize();
}

LabelNode::~LabelNode()
{
    m_opacity->removeChildNode(m_textTexture);
    m_textTexture->setOwnsTexture(true);
    delete m_textTexture;
}

void LabelNode::initialize()
{
    switch (m_labelType)
    {
        case LabelsItem::label_t::PLANET_LABEL:
        case LabelsItem::label_t::SATURN_MOON_LABEL:
        case LabelsItem::label_t::JUPITER_MOON_LABEL:
        case LabelsItem::label_t::COMET_LABEL:
        case LabelsItem::label_t::RUDE_LABEL:
        case LabelsItem::label_t::ASTEROID_LABEL:
            m_schemeColor = "PNameColor";
            m_zoomFont    = true;
            break;
        case LabelsItem::label_t::DEEP_SKY_LABEL:
        case LabelsItem::label_t::DSO_MESSIER_LABEL:
        case LabelsItem::label_t::DSO_NGC_LABEL:
        case LabelsItem::label_t::DSO_IC_LABEL:
        case LabelsItem::label_t::DSO_OTHER_LABEL:
        case LabelsItem::label_t::CATALOG_DSO_LABEL:
            m_schemeColor = "DSNameColor";
            m_zoomFont    = true;
            break;
        case LabelsItem::label_t::TELESCOPE_SYMBOL:
            m_schemeColor = "TargetColor";
            m_zoomFont    = true;
            break;
        case LabelsItem::label_t::CONSTEL_NAME_LABEL:
            m_schemeColor = "CNameColor";
            break;
        case LabelsItem::label_t::STAR_LABEL:
        case LabelsItem::label_t::CATALOG_STAR_LABEL:
            m_schemeColor = "SNameColor";
            break;
        default:
            m_schemeColor = "UserLabelColor";
            break;
    }

    createTexture(KStarsData::Instance()->colorScheme()->colorNamed(m_schemeColor));
    m_opacity->appendChildNode(m_textTexture);
}

void LabelNode::createTexture(QColor color)
{
    switch (m_labelType)
    {
        case LabelsItem::label_t::SATURN_MOON_LABEL:
        case LabelsItem::label_t::JUPITER_MOON_LABEL:
            SkyLabeler::Instance()->shrinkFont(2);
            break;
        default:
            break;
    }

    QSGTexture *oldTexture = m_textTexture->texture();

    m_textTexture->setTexture(SkyMapLite::Instance()->textToTexture(m_name, color, m_zoomFont));
    m_color = color;

    if (m_zoomFont)
        m_fontSize = SkyLabeler::Instance()->drawFont().pointSize();

    switch (m_labelType)
    {
        case LabelsItem::label_t::SATURN_MOON_LABEL:
        case LabelsItem::label_t::JUPITER_MOON_LABEL:
            SkyLabeler::Instance()->resetFont();
            break;
        default:
            break;
    }

    if (oldTexture)
        delete oldTexture;

    m_textSize     = m_textTexture->texture()->textureSize();
    QRectF oldRect = m_textTexture->rect();
    qreal ratio    = SkyMapLite::Instance()->window()->effectiveDevicePixelRatio();

    m_textTexture->setRect(QRect(oldRect.x(), oldRect.y(), m_textSize.width() / ratio, m_textSize.height() / ratio));
}

void LabelNode::changePos(QPointF pos)
{
    QMatrix4x4 m(1, 0, 0, pos.x(), 0, 1, 0, pos.y(), 0, 0, 1, 0, 0, 0, 0, 1);
    //m.translate(-0.5*size.width(), -0.5*size.height());

    setMatrix(m);
    markDirty(QSGNode::DirtyMatrix);
}

void LabelNode::setLabelPos(QPointF pos)
{
    show();
    qreal ratio = SkyMapLite::Instance()->window()->effectiveDevicePixelRatio();
    //We need to subtract the height of texture from final y to follow the way QPainter draws the text
    if (m_skyObject)
        labelPos = QPointF(pos.x() + m_skyObject->labelOffset(),
                           pos.y() + m_skyObject->labelOffset() - m_textSize.height() / ratio);
    else
        labelPos = QPointF(pos.x(), pos.y());
}

void LabelNode::update()
{
    QColor newColor = KStarsData::Instance()->colorScheme()->colorNamed(m_schemeColor);
    if ((m_zoomFont && m_fontSize != SkyLabeler::Instance()->skyFont().pointSize()) || m_color != newColor)
    {
        createTexture(newColor);
    }
    changePos(labelPos);
}
