#include "UnshapedRecipie.h"

#include <Bild.h>
#include <XML.h>

UnshapedRecipieElement::UnshapedRecipieElement()
    : Framework::UIMLElement()
{}

//! prüft, ob dieses UIML Element für ein bestimmtes xml Element zuständig
//! ist
bool UnshapedRecipieElement::isApplicableFor(Framework::XML::Element& element)
{
    return element.getName().istGleich("recipie")
        && element.getAttributeValue("type").istGleich("unshaped");
}

//! erstellt eine neue Zeichnung zu einem gegebenen xml Element
Framework::Zeichnung* UnshapedRecipieElement::parseElement(
    Framework::XML::Element& element, Framework::UIMLContainer& generalFactory)
{
    UnshapedRecipie* recipie = new UnshapedRecipie();

    element.selectChildsByName("ingredients")
        .selectChildren()
        .forEach([recipie, &generalFactory](Framework::XML::Element* zElement) {
            recipie->addIngredient(
                generalFactory.parseElement(*zElement, generalFactory));
        });

    element.selectChildsByName("outputs").selectChildren().forEach(
        [recipie, &generalFactory](Framework::XML::Element* zElement) {
            recipie->addOutput(
                generalFactory.parseElement(*zElement, generalFactory));
        });

    return recipie;
}

bool UnshapedRecipieElement::updateElement(Framework::XML::Element& element,
    Framework::Zeichnung& z,
    Framework::UIMLContainer& generalFactory)
{
    return false;
}

//! wendet die layout parameter zu einer Zeichnung an
void UnshapedRecipieElement::layout(Framework::XML::Element& element,
    Framework::Zeichnung& z,
    int pWidth,
    int pHeight,
    Framework::UIMLContainer& generalLayouter)
{
    UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
    element.selectChildren().selectChildren().forEach(
        [&z, &generalLayouter](Framework::XML::Element* zElement) {
            Framework::Zeichnung* child = 0;
            if (zElement->hasAttribute("id"))
            {
                child = generalLayouter.zZeichnungById(
                    zElement->getAttributeValue("id"));
            }
            if (child)
            {
                generalLayouter.layout(*zElement,
                    *child,
                    z.getBreite(),
                    z.getHeight(),
                    generalLayouter);
            }
        });
}

UnshapedRecipie::UnshapedRecipie()
    : Framework::ZeichnungHintergrund()
{
    setStyle(Framework::Zeichnung::Style::Erlaubt
             | Framework::Zeichnung::Style::Sichtbar);
}

void UnshapedRecipie::addIngredient(Zeichnung* ingredient)
{
    ingredients.add(ingredient);
}

void UnshapedRecipie::addOutput(Zeichnung* output)
{
    outputs.add(output);
}

bool UnshapedRecipie::tick(double tickVal)
{
    bool ret = false;
    for (Zeichnung* ingredient : ingredients)
    {
        ret |= ingredient->tick(tickVal);
    }
    for (Zeichnung* output : outputs)
    {
        ret |= output->tick(tickVal);
    }
    return ret;
}

void UnshapedRecipie::render(Framework::Bild& rObj)
{
    if (!hatStyle(Zeichnung::Style::Sichtbar)) return;
    ZeichnungHintergrund::render(rObj);
    if (!rObj.setDrawOptions(pos.x, pos.y, gr.x, gr.y)) return;
    int x = 0;
    int y = 0;
    int width = MIN(3, ingredients.getEintragAnzahl());
    for (Zeichnung* ingredient : ingredients)
    {
        ingredient->setX(x);
        ingredient->setY(y);
        ingredient->render(rObj);
        x += 60;
        if (x >= 3 * 60)
        {
            x = 0;
            y += 60;
        }
    }
    rObj.fillRegion(width * 60, gr.y / 2 - 5, 25, 10, 0xFF52525E);
    rObj.drawDreieck(Framework::Punkt(3 * 60 + 25, gr.y / 2 - 15),
        Framework::Punkt(width * 60 + 40, gr.y / 2),
        Framework::Punkt(width * 60 + 25, gr.y / 2 + 15),
        0xFF52525E);
    x = width * 60 + 50;
    int oldy = y;
    y = 0;
    for (Zeichnung* output : outputs)
    {
        output->setX(x);
        output->setY(y);
        output->render(rObj);
        y += 60;
    }
    int height = MAX(3, outputs.getEintragAnzahl());
    if (getBreite() != width * 60 + 50 + 50 && getHeight() != height)
    {
        setSize(width * 60 + 50 + 50, MAX(oldy + 50, y + 50));
    }
    rObj.releaseDrawOptions();
}

void UnshapedRecipie::doMausEreignis(Framework::MausEreignis& me, bool userRet)
{
    for (Zeichnung* ingredient : ingredients)
    {
        ingredient->doPublicMausEreignis(me);
    }
    for (Zeichnung* output : outputs)
    {
        output->doPublicMausEreignis(me);
    }
}