#pragma once

#include "DataElement.hpp"

/*
   Class: MorphElement

     Implements a morphable data element. Morph elements can either have the initial shape
     of a bar or a pie slice and can then morph to the other shape.

     *Inherits* from <DataElement>.
*/
class MorphElement: public DataElement {
  public:
    /*
       Constructor: MorphElement

         Initializes the object as a copy of a bar data element.

       Parameters:

         pDataEntry - Pointer to the data entry object that shall be represented by the morph element.
         pResultElement - Pointer to the morph element whose shape shall be the result of the morphing process.
         iVerticesPerSide - Number of vertices of the bar.
         fLeft - The x value of the bar.
         fTop - The upper y value of the bar.
         fBottom - The lower y value of the bar.
         fWidth - The width of the bar.
    */
    MorphElement(DataEntry* pDataEntry, MorphElement* pResultElement, int iVerticesPerSide,
      float fLeft, float fTop, float fBottom, float fWidth);

    /*
       Constructor: MorphElement

         Initializes the object as a copy of a pie slice data element.

       Parameters:

         pDataEntry - Pointer to the data entry object that shall be represented by the morph element.
         pResultElement - Pointer to the morph element whose shape shall be the result of the morphing process.
         iVerticesPerSide - Number of outter vertices of the pie slice.
         fBeginValue - Accumulated data entry values of predecessor pie slices.
         fWidth - Data entry value of the pie slice.
    */
    MorphElement(DataEntry* pDataEntry, MorphElement* pResultElement, int iVerticesPerSide,
      float fBeginValue, float fWidth);

    /*
       Destructor: ~MorphElement

         Releases all allocated resources.
    */
    ~MorphElement();
    
    /*
       Function: Draw

         Draws the morph element. *Inherited* from <AlterableObject>.

       Parameters:

         pPainter - The QPainter object that shall be used for painting.
    */
    void Draw(QPainter* pPainter);

    /*
       Function: DrawLabels

         Unused function. *Inherited* from <AlterableObject>.

       Parameters:

         pPainter - Unused parameter.
    */
    void DrawLabels(QPainter* pPainter);

    /*
       Function: ChangePosition

         Changes the position of the morph element. *Inherited* from <AlterableObject>.

       Parameters:

         fDeltaLeft - Total horizontal distance.
         fDeltaTop - Total vertical distance according to the upper vertices.
         fDeltaBottom - Total vertical distance according to the lower vertices. Default value is 0.0f.
    */
    void ChangePosition(float fDeltaLeft, float fDeltaTop, float fDeltaBottom = 0.0f);

    /*
       Function: Scale

         Scales the object. *Inherited* from <DataElement>.

       Parameters:

         fDeltaWidth - Total horizontal scaling value.
         fDeltaHeight - Total vertical scaling value.
    */
    void Scale(float fDeltaWidth, float fDeltaHeight);

    /*
       Function: ChangeAlpha

         Changes the alpha value of the morph element. *Inherited* from <AlterableObject>.

       Parameters:

         fDeltaAlpha - Change of alpha value. Default value is 0.0f.
    */
    void ChangeAlpha(float fDeltaAlpha);

    /*
       Function: Morph

         Morphs the object to the shape of the result morph element by moving the single
         vertices according to the morph steps.

       Parameters:

         vMorphSteps - An array containing X and Y moving offsets for every vertex of the morph element.
    */
    void Morph(glm::vec2* vMorphSteps);

    /*
       Function: GetAllPoints

         Returns all vertices of the morph element.

       Returns:

         An array containing all vertices of the morph element.
    */
    glm::vec4* GetAllPoints();

    /*
       Function: GetVertexCount

         Returns the total number of vertices of the element.

       Returns:

         The total number of vertices of the element.
    */
    int GetVertexCount();

    /*
       Function: GetResultElement

         Returns the pointer to the specified result morph element.

       Returns:

         The pointer to the specified result morph element. For a specified result morph element itself, this returns NULL.
    */
    MorphElement* GetResultElement();

  private:
    int iVerticesPerSide;
    float fBeginValue;
    MorphElement* pResultElement;
};