#include "ExampleControl.h"

#include "CustomExtensionFactory.h"

#include "GfxWrap.h"

#ifdef GUILIANI_STREAM_GUI
#include "GUIStreamReader.h"
#endif

#ifdef GUILIANI_WRITE_GUI
#include "GUIStreamWriter.h"
#include "GUIControlResource.h"
#endif

#include "GUIMemLeakWatcher.h" // <-- has to be the last include

#define EXAMPLE_CONTROL_CLASS_VERSION 3
// The minimal class version allowed.
#define EXAMPLE_CONTROL_CLASS_MIN_VERSION 1

// CGUIExampleControl
static const eC_Int CTL_EXAMPLE_UID = 0x34d73417;

const eC_UInt ExampleControl::INDEX_INNERCOLOR = 0;
const eC_UInt ExampleControl::INDEX_BORDERCOLOR = 1;

eC_Bool ExampleControl::ms_bInitialized = GETEXTENSIONSFACTORY->RegisterControl(ControlDescriptor(CTL_EXAMPLE_UID, "ExampleControl", ExampleControl::Create));

ExampleControl::ExampleControl(
    CGUICompositeObject* const pkParent,
    const eC_Value& vX, const eC_Value& vY,
    const eC_Value& vWidth, const eC_Value& vHeight,
    eC_UInt uiInnerColor, eC_UInt uiBorderColor,
    eC_Value vBorderWidth,
    const ObjectHandle_t &eID) :
    CGUIObject(pkParent, vX, vY, vWidth, vHeight, eID),
    CGUIColorPropertyObserver(),
    m_vBorderWidth(vBorderWidth)
{
    SetXMLTag("ExampleControl");

    AddColorProperty(INDEX_INNERCOLOR, false, uiInnerColor, DUMMY_PROPERTY);
    AddColorProperty(INDEX_BORDERCOLOR, false, uiBorderColor, DUMMY_PROPERTY);
}

eC_UInt ExampleControl::GetInnerColor() const
{
    return GetColorValue(INDEX_INNERCOLOR);
}

eC_UInt ExampleControl::GetBorderColor() const
{
    return GetColorValue(INDEX_BORDERCOLOR);
}

eC_Value ExampleControl::GetBorderWidth() const
{
    return m_vBorderWidth;
}

void ExampleControl::SetInnerColor(const eC_UInt& uiInnerColor)
{
    SetColorProperty(INDEX_INNERCOLOR, uiInnerColor);
}

void ExampleControl::SetInnerColor(const GlobalProperty_t& eInnerColor)
{
    SetColorProperty(INDEX_INNERCOLOR, eInnerColor);
}

void ExampleControl::SetBorderColor(const eC_UInt& uiBorderColor)
{
    SetColorProperty(INDEX_BORDERCOLOR, uiBorderColor);
}

void ExampleControl::SetBorderColor(const GlobalProperty_t& eBorderColor)
{
    SetColorProperty(INDEX_BORDERCOLOR, eBorderColor);
}

void ExampleControl::SetBorderWidth(eC_Value vBorderWidth)
{
    if (vBorderWidth != m_vBorderWidth)
    {
        m_vBorderWidth = vBorderWidth;
        InvalidateArea();
    }
}

eC_Bool ExampleControl::DoDraw()
{
    CGUIRect kAbsRect(GetAbsRect());
    if (m_vBorderWidth != eC_FromInt(0))
    {
        GETGFX.SetForegroundColor(GetBorderColor());
        GETGFX.FilledRect(kAbsRect);
        kAbsRect.Expand(-m_vBorderWidth);
    }
    GETGFX.SetForegroundColor(GetInnerColor());
    GETGFX.FilledRect(kAbsRect);
    return true;
}

#if defined(GUILIANI_STREAM_GUI)
void ExampleControl::ReadFromStream()
{
    const eC_UInt cuiVersion = ReadStreamingHeader(EXAMPLE_CONTROL_CLASS_VERSION, EXAMPLE_CONTROL_CLASS_MIN_VERSION);

    // switch versions
    if (cuiVersion <= 1)
    {
        SetInnerColor(GETINPUTSTREAM.READ_HEX("InnerColor"));
        SetBorderColor(GETINPUTSTREAM.READ_HEX("BorderColor"));
        m_vBorderWidth = eC_FromFloat(GETINPUTSTREAM.READ_FLOAT("BorderWidth"));

        CGUIObject::ReadFromStream();
    }
    else
    {
        // always base-class first
        CGUIObject::ReadFromStream();

        // remove attribute-group start
        GETINPUTSTREAM.DeleteCommentTag("ExampleControl");

        if (cuiVersion >= 3)
        {
            // new handling of color-resources which can now be also properties
            SetColorProperty(INDEX_INNERCOLOR, GETINPUTSTREAM.READ_COLOR("InnerColor"));
            SetColorProperty(INDEX_BORDERCOLOR, GETINPUTSTREAM.READ_COLOR("BorderColor"));
        }
        else
        {
            SetInnerColor(GETINPUTSTREAM.READ_HEX("InnerColor"));
            SetBorderColor(GETINPUTSTREAM.READ_HEX("BorderColor"));
        }

        m_vBorderWidth = eC_FromFloat(GETINPUTSTREAM.READ_FLOAT("BorderWidth"));

        // remove attribute-group end
        GETINPUTSTREAM.DeleteCommentTag("/ExampleControl");
    }
}
#endif

#if defined(GUILIANI_WRITE_GUI)
void ExampleControl::WriteToStream(const eC_Bool bWriteClassID)
{
    WriteStreamingHeader(bWriteClassID, XMLTAG_CONTROLCLASSID, CTL_EXAMPLE_UID, EXAMPLE_CONTROL_CLASS_VERSION);

    CGUIObject::WriteToStream();

    // write attribute-group start
    GETOUTPUTSTREAM.WriteCommentTag("ExampleControl");

    GETOUTPUTSTREAM.WriteColor(GetColorProperty(INDEX_INNERCOLOR), "InnerColor");
    GETOUTPUTSTREAM.WriteColor(GetColorProperty(INDEX_BORDERCOLOR), "BorderColor");

    GETOUTPUTSTREAM.WriteFloat(eC_ToFloat(m_vBorderWidth), "BorderWidth");

    // write attribute-group end
    GETOUTPUTSTREAM.WriteCommentTag("/ExampleControl");

    WriteStreamingFooter(bWriteClassID);
}
#endif
