#pragma once

#include "Zeichnung.h"
#include "Trie.h"
#include "Array.h"
#include "UIInitialization.h"

namespace Framework
{
    class Text;
    class ObjTabelle;
    class Schrift;
    class Bildschirm;

    namespace XML
    {
        class Element;
    }

    /**
      KSG UIML Standart
      possible XML elements:
        - uimlview (the root element of uiml),
        - class (only as direct child of uimlview),
        - textfield,
        - button,
        - check, (KontrollKnopf)
        - text,
        - textarea,
        - table (allowed child elements: tr),
        - tr (allowed child elements: textfield, button, table, text, textarea, frame),
        - frame (allowed child elements: textfield, button, table, text, textarea, frame).
      possible global XML attributes:
        - id (string should be unique),
        - x (integer, optional % char at end),
        - y (integer, optional % char at end),
        - width (integer, optional % char at end),
        - height (integer, optional % char at end),
        - margin (integer, optional % char at end),
        - margin-left (integer, optional % char at end),
        - margin-top (integer, optional % char at end),
        - margin-right (integer, optional % char at end),
        - margin-bottom (integer, optional % char at end),
        - align-left (string (id values of other elements or keywords: start, end)),
        - align-top (string (id values of other elements or keywords: start, end)),
        - align-bottom ((string (id values of other elements or keywords: start, end)),
        - align-right (string (id values of other elements or keywords: start, end)),
        - tooltip (string),
        - style (hex __int64),
        - class (string (id of class element))

        attribute die sich gegenseitig ausschließen:
        - align-left / align-right
        - align-top / align-bottom

      spezific attributes:
         - font-size (textfield, text, textarea, button)
         - text-align (textfield, text, textarea)
         - text-align-horizontal (textfield, text, textarea)
         - text-align-vertical (textfield, text, textarea)

      example:
        \code
        <view>
          <textfield id="element_at_top_left" align-left="start", align-top="start", margin-left="5", margin-top="5" width="90%" height="30"/>
          <table id="element_below_textfield" align-left="start", aliign-top="element_at_top_left", margin-left="5", margin-top="5" width="90%" height="300">
            <tr>
              <button id="a_button_in_a_table"/>
              <textfield id="a_textfield_in_a_table"/>
            </tr>
          </table>
        </view>
        \endcode
    */
    class UIMLView : public ZeichnungHintergrund
    {
    private:
        UIInit init;
        Trie< Zeichnung > *members;
        XML::Element *dom;
        int nextId;
        void parseTable( Iterator<XML::Element*> childs, ObjTabelle *table );
        void parseFrame( Iterator<XML::Element*> childs, Fenster *frame );
        Zeichnung *parseElement( XML::Element *e );
        void layout( XML::Element *e, int pWidth, int pHeight );
        //! Verarbeitet ein Maus Ereignis. Wird vom Framework automatisch aufgerufen.
        //! \param me Das Ereignis
        DLLEXPORT virtual void doMausEreignis( MausEreignis &me, bool userRet ) override;

    public:
        //! Erstellt eine UIML View
        DLLEXPORT UIMLView();
        //! Erstellt eine UIML View zu einem UIML Text
        //! \param uiml Ein xml element gemät des KSG UIML standarts
        //! \param screen Ein zeiger für den Belschirm auf dem die tooltips angezeigt werden sollen
        //! \param schrift Die schrift mit der der Text gezeichnet werden soll
        DLLEXPORT UIMLView( XML::Element *uiml, UIInit &init );
        //! Erstellt eine UIML View zu einem UIML Text
        //! \param uiml Ein xml text gemät des KSG UIML standarts
        //! \param screen Ein zeiger für den Belschirm auf dem die tooltips angezeigt werden sollen
        //! \param schrift Die schrift mit der der Text gezeichnet werden soll
        DLLEXPORT UIMLView( Text uiml, UIInit &init );
        DLLEXPORT ~UIMLView();
        //! setzt den inhalt der view
        //! \param uiml Ein xml element gemät des KSG UIML standarts
        DLLEXPORT void setUIML( XML::Element *uiml );
        //! setzt den inhalt der view
        //! \param uiml Ein xml text gemät des KSG UIML standarts
        DLLEXPORT void setUIML( Text uiml );
        //! aktualisiert größe und position aller Zeichnungen gemäß den spezifikationen in UIML
        DLLEXPORT void layout();
        //! fügt ein element hinzu
        //! \param uiml Ein xml text gemät des KSG UIML standarts, welcher das neue Objekt darstellt
        //! \return id des neuen Elements
        DLLEXPORT Text addMember( Text uiml );
        //! fügt ein element zu einem Elternelement hinzu (funktioniert momentan nur mit frame Objekten)
        //! \param uiml Ein xml text gemät des KSG UIML standarts, welcher das neue Objekt darstellt
        //! \return id des neuen Elements
        DLLEXPORT Text addMember( Text uiml, Text parentId );
        //! entfernt ein element
        //! \param id id des Elements
        DLLEXPORT void removeMember( Text id );
        //! Gibt eine zeichnung zurück, welche in uiml eine bestimmte id hat
        //! \param id die id der Zeichnung
        DLLEXPORT Zeichnung *zZeichnung( Text id );
        //! Verarbeitet ein Tastatur Ereignis. Wird vom Framework automatisch aufgerufen
        //! \param te Das Ereignis
        DLLEXPORT virtual void doTastaturEreignis( TastaturEreignis &te );
        //! Updated den Zeichenhintergrund
        //! \param tickVal Die vergangene Zeit in Sekunden, die seit dem Letzten Aufruf dieser Funktion verstrichen ist
        //! \return 1, wenn das Bild neu gezeichnet werden muss. 0 sonnst
        DLLEXPORT bool tick( double tickVal ) override;
        //! Zeichnet den Hintergrund eines Zeichnunges nach rObj
        DLLEXPORT void render( Bild &rObj ) override;
        //! Gibt den Dom Tree ohne erhöhten reference counter zurück
        //! Änderungen am Dom Tree sollten vermieden werden (nur änderungen von attributen einzelner elemente sind erlaubt)
        DLLEXPORT XML::Element *zDom() const;
        //! Gibt den Dom Tree zurück
        //! Änderungen am Dom Tree sollten vermieden werden (nur änderungen von attributen einzelner elemente sind erlaubt)
        DLLEXPORT XML::Element *getDom() const;
    };
}