#include "graphics.hpp"
#include "label.h"
#include <iostream>

using namespace genv;
using namespace std;

int label::cnt;

/// ---------------------------------------- Konstruktorok ----------------------------------------------------------
void label::labelInit()
{
    cnt++;
    marginSide = 10; marginTop = 7;
    visible = true;
    background = false;
    fontColor = Black;
    backgroundColor = "#ffffff";
    align = align_left;
    tabStop = false;
    display = trimBegin;
}

label::label(int x0, int y0, unsigned int width0, unsigned int height0) : widget(x0, y0, width0, height0)
{
    labelInit();
    setText("Label" + convert(cnt));
}

label::label(int x0, int y0, unsigned int width0, unsigned int height0, string txt) : widget(x0, y0, width0, height0)
{
    labelInit();
    setText(txt);
}
/// ----------------------------------------------------------------------------------------------------------------


/// --------------------------------------------- Get/Set ----------------------------------------------------------
void label::setText(string txt)
{
    Text = txt;
    textRefresh();
}

string label::getText() const { return Text; }

void label::setMargin(int mS, int mT)
{
    marginSide = mS;
    marginTop = mT;
}
/// ----------------------------------------------------------------------------------------------------------------


/// --------------------------------- Mûködéshez szükséges függvények ------------------------------------------------
void label::textRefresh() const
{
    dispText = Text;

    if (marginSide * 2 + gout.twidth(Text) < width && display != autoSize) return;

    switch (display)
    {
    case autoSize :
        width = marginSide * 2 + gout.twidth(Text);
        break;
    case trimBegin :
        for (unsigned int i = Text.length()-1; i > 0 ; i--)
            {
                dispText = "..." + Text.substr(i, Text.length());
                if (width < marginSide * 2 + gout.twidth(dispText) + 4) break;
            }
        break;
    case trimEnd :
        for (unsigned int i = Text.length()-1; i > 0 ; i--)
        {
            dispText = Text.substr(0,i) + "...";
            if (width > marginSide + gout.twidth(dispText) + 4) break;
        }
        break;
    case wordWrap :
        unsigned int numberOfRows = 1;
        string row;
        dispText = "";
        unsigned int i = 0;
        unsigned int prevPos = 0;
        // Ebben a ciklusban nem karakterenként, hanem szavanként megyek végig a szövegen
        while (i < Text.length())
        {
            prevPos = i;
            i = Text.find(' ',prevPos + 1);
            if (width - marginSide*2 < gout.twidth(row + Text.substr(prevPos, i-prevPos))) // Ha már nem fér ki a következõ szó
            {
                dispText += row + "\n";
                numberOfRows++;

                // Megszámolom az enterek számát, mivel ez is növeli a sorok számát
                unsigned int prevEnterPos = 0;
                unsigned int j = row.find("\n");;
                while ( j < row.length())
                {
                    j = row.find("\n" ,prevEnterPos + 2);
                    numberOfRows++;
                    prevEnterPos = j;
                }

                // A következõ szó már csak a következõ sorba fér ki, és nem kell az elejére a space
                row = Text.substr(prevPos + 1, i - prevPos);
            }
            else
                row += Text.substr(prevPos, i - prevPos);
        }
        dispText += row;
        numberOfRows++;

        // És végsõsoron akár a szövegdoboz magasságát is hozzáigazíthatom a szöveghez
    height = numberOfRows * (gout.cascent() + gout.cdescent()) + marginTop;
        break;
    }
}

void label::labelDraw() const
{
    if (X < x + width) std::cerr << "Object is out of window! (X < x + width) : label" + convert(cnt) + " - label::labelDraw" << std::endl;
    else if (Y < y + height) std::cerr << "Object is out of window! (Y < y + height) - label" + convert(cnt) + " - label::labelDraw" << std::endl;

    textRefresh();

    if (background)
    {
        colorize(backgroundColor);
        gout << move_to(x,y) << box(width, height);
    }

    colorize(fontColor);
    if (display == wordWrap)
    {
        gout << move_to(x + marginSide, y + marginTop + gout.cascent()) << text(dispText);
    }
    else if (align == align_right)
    {
        gout << move_to(x + width - gout.twidth(dispText)  - marginSide, y + marginTop + gout.cascent()) << text(dispText);
    }
    else if (align == align_center)
    {
        gout << move_to(x + (width - gout.twidth(dispText))/2, y + marginTop + gout.cascent()) << text(dispText);
    }
    else
    {
        gout << move_to(x + marginSide, y + marginTop + gout.cascent()) << text(dispText);
    }
}

void label::draw() const
{
    if (visible) labelDraw();
}
/// ----------------------------------------------------------------------------------------------------------------


