#include "M2DPreview.h"

#include "AlphaField.h"
#include "Image.h"
#include "Globals.h"
#include "MouseEvent.h"
#include "Model2D.h"
#include "Border.h"
#include "ToolTip.h"

using namespace Framework;

// Contents of the M2DPreview class from M2DPreview.h
// Constructor
M2DPreview::M2DPreview()
    : DrawableBackground()
{
    mdl = 0;
    mx = -1;
    my = -1;
    af = 0;
    ram = 0;
}

// Destructor
M2DPreview::~M2DPreview()
{
    if (mdl) mdl->release();
    if (ram) ram->release();
    if (af) af->release();
}

void M2DPreview::doMouseEvent(MouseEvent& me, bool userRet)
{
    if (hasStyleNot(Style::Allowed) || !userRet) return;
    if (hasStyle(Style::UsrScale))
    {
        if (mdl && me.id == ME_UScroll) mdl->addSize(0.01f);
        if (mdl && me.id == ME_DScroll) mdl->addSize(-0.01f);
    }
    if (me.id == ME_RLeft || me.id == ME_RRight || me.id == ME_Leaves)
    {
        mx = -1;
        my = -1;
    }
    if (mdl && me.id == ME_Move)
    {
        if (mx != -1 && my != -1)
        {
            if (getMouseState(M_Left) && hasStyle(Style::UsrMove))
                mdl->setPosition(
                    mdl->getPosition() + Point(me.mx - mx, me.my - my));
            if (getMouseState(M_Right) && hasStyle(Style::UsrRot))
            {
                if (me.mx > gr.x / 2)
                    mdl->addRotation(0.01f * (float)(me.my - my));
                else
                    mdl->addRotation(-0.01f * (float)(me.my - my));
                if (me.my > gr.y / 2)
                    mdl->addRotation(-0.01f * (float)(me.mx - mx));
                else
                    mdl->addRotation(0.01f * (float)(me.mx - mx));
            }
            mx = me.mx;
            my = me.my;
        }
    }
    if (me.id == ME_PLeft || me.id == ME_PRight)
    {
        mx = me.mx;
        my = me.my;
    }
    me.processed = 1;
}

// non-constant
void M2DPreview::setModel2DZ(Model2D* mdl)
{
    if (this->mdl) this->mdl->release();
    this->mdl = mdl;
    rend = 1;
}

void M2DPreview::setModel2D(Model2DData* mdl)
{
    if (!this->mdl) this->mdl = new Model2D();
    this->mdl->setModel(mdl);
    rend = 1;
}

bool M2DPreview::tick(double tv)
{
    rend |= mdl ? mdl->tick(tv) : 0;
    rend |= af ? af->tick(tv) : 0;
    rend |= ram ? ram->tick(tv) : 0;
    return DrawableBackground::tick(tv);
}

void M2DPreview::render(Image& rb)
{
    removeStyle(Style::VScroll | Style::HScroll);
    if (hasStyleNot(Style::Visible)) return;
    DrawableBackground::render(rb);
    if (!rb.setDrawOptions(innenPosition, innenSize)) return;
    if (mdl)
    {
        int rbr = border && hasStyle(Style::Border) ? border->getRWidth() : 0;
        rb.addScrollOffset(-gr.x / 2 + rbr, -gr.y / 2 + rbr);
        mdl->render(rb);
    }
    rb.releaseDrawOptions();
}

// constant
Model2D* M2DPreview::zModel() const
{
    return mdl;
}

Model2D* M2DPreview::getModel() const
{
    return mdl ? dynamic_cast<Model2D*>(mdl->getThis()) : 0;
}

Drawable* M2DPreview::duplicate() const
{
    M2DPreview* ret = new M2DPreview();
    if (mdl) ret->setModel2D(mdl->getModel());
    if (border) ret->setBorderZ((Border*)border->duplicate());
    if (backgroundFeld)
        ret->setAlphaFieldZ((AlphaField*)backgroundFeld->duplicate());
    ret->setBackgroundColor(bgF);
    return ret;
}