#pragma once

#include "AlterableObject.hpp"
#include "Axis.hpp"
#include "GridLine.hpp"
#include "Label.hpp"
#include "DataElement.hpp"
#include "DataSet.hpp"

/*
   Class: Chart

     *Abstract* class that implements the skeleton of a chart.

     *Inherits* from <AlterableObject>.
*/
class Chart: public AlterableObject {
  public:
    /*
       Constructor: Chart

         Initializes the object.
    */
    Chart();

    /*
       Destructor: ~Chart

         *Virtual*. Releases all allocated resources.
    */
    virtual ~Chart();


    /*
       Function: AddDataElement

         Adds the data element to the chart.

       Parameters:

         pDataElement - The data element to be added.
    */
    void AddDataElement(DataElement* pDataElement);

    /*
       Function: GetDataElements

         Returns a vector containing all data elements of the chart.

       Returns:

         A vector containing all data elements of the chart.
    */
    std::vector<DataElement*> GetDataElements();

    /*
       Function: AddAxis

         Adds the axis to the chart.

       Parameters:

         pAxis - The axis to be added.
    */
    void AddAxis(Axis* pAxis);

    /*
       Function: GetAxes

         Returns a vector containing all axes of the chart.

       Returns:

         A vector containing all axes of the chart.
    */
    std::vector<Axis*> GetAxes();

    /*
       Function: AddGridLine

         Adds the grid line to the chart.

       Parameters:

         pGridLine - The grid line to be added.
    */
    void AddGridLine(GridLine* pGridLine);

    /*
       Function: GetGridLines

         Returns a vector containing all grid lines of the chart.

       Returns:

         A vector containing all grid lines of the chart.
    */
    std::vector<GridLine*> GetGridLines();

    /*
       Function: AddLabel

         Adds the label to the chart.

       Parameters:

         pLabel - The label to be added.
    */
    void AddLabel(Label* pLabel);

    /*
       Function: GetLabels

         Returns a vector containing all labels of the chart.

       Returns:

         A vector containing all labels of the chart.
    */
    std::vector<Label*> GetLabels();

    /*
       Function: GetDataSet

         Returns the data set represented by the chart.

       Returns:

         The data set represented by the chart.
    */
    DataSet* GetDataSet();

    /*
       Function: GetConnectedDataElement

         Returns the data element which represents the given data entry. If no such data element exists, NULL is returned.

       Parameters:

         pDataEntry - Pointer to the data entry to be searched.

       Returns:

         The data element which represents the given data entry if present, else NULL.
    */
    DataElement* GetConnectedDataElement(DataEntry* pDataEntry);

    /*
       Function: GetHighestVisibleValue

         Returns the highest data entry value that is visible (not filtered) in the current chart. If no data entries exist, 0.0 is returned.

       Returns:

         The highest data entry value that is visible in the current chart.
    */
    double GetHighestVisibleValue();

  protected:
    std::vector<DataElement*> vDataElements;
    std::vector<Axis*> vAxes;
    std::vector<GridLine*> vGridLines;
    std::vector<Label*> vLabels;

    DataSet* pDataSet;
    std::vector<DataEntry*> vVisibleDataEntries;
};