<?php
namespace Ceetrox\Sidekick\Views\Limitless\Linechart\ChartManager;

Class ChartDataManager {

    private $categories;
    private $series;
    private $numberOfCharts;
    private $titles;
    private $colors;
    private $hasBoundaryGap;
    private $isInverted;
    private $hasDataZoom;
    private $animationDuration;
    private $yAxisLabelValueFormat;
    private $rawData;

    // these attributes should also be available on seriesData object.
    private $showPointValues;
    private $isStacked;
    private $isArea;
    private $markLine;

    public function __construct()
    {
        $this->categories = [];
        $this->series = new Series();
        $this->numberOfCharts = 1;
        $this->colors = [];
        $this->hasBoundaryGap = false;
        $this->isInverted = false;
        $this->hasDataZoom = false;
        $this->animationDuration = 750;
        $this->yAxisLabelValueFormat = null;
        $this->rawData = null;

        $this->showPointValues = false;
        $this->isStacked = false;
        $this->isArea = false;
        $this->markLine = null;
    }

    public static function getInstance(): ChartDataManager
    {
        return new self;
    }

    public static function getSeriesDataInstance(): SeriesData
    {
        return new SeriesData();
    }

    public function getSeries() : Series
    {
        return $this->series;
    }

    private function getCategories() : array
    {
        return $this->categories;
    }

    private function getNumberOfCharts() : int
    {
        return $this->series->numberOfCharts();
    }

    private function getTitles()
    {
        return $this->titles;
    }

    private function getColors() : array
    {
        return $this->colors;
    }

    private function getHasBoundaryGap() : bool
    {
        return $this->hasBoundaryGap;
    }

    private function getIsInverted() : bool
    {
        return $this->isInverted;
    }

    private function getHasDataZoom() : bool
    {
        return $this->hasDataZoom;
    }

    private function getAnimationDuration() : int
    {
        return $this->animationDuration;
    }

    private function getYAxisLabelValueFormat() : ?string
    {
        return $this->yAxisLabelValueFormat;
    }

    private function getRawData() : ?string
    {
        return $this->rawData;
    }

    private function getShowPointValues() : bool
    {
        return $this->showPointValues;
    }

    private function getIsStacked() : bool
    {
        return $this->isStacked;
    }

    private function getIsArea() : bool
    {
        return $this->isArea;
    }

    private function getMarkLine() : ?string
    {
        return $this->markLine;
    }

    public function setTitle($title) : ChartDataManager
    {
        if(is_array($title)) {
            $this->titles = array_merge($this->titles, $title);
        } else {
            $this->titles[] = $title;
        }

        return $this;
    }

    public function setColors($color) : ChartDataManager
    {
        if(is_array($color)) {
            $this->colors = array_merge($this->colors, $color);
        } else {
            $this->colors[] = $color;
        }

        return $this;
    }

    public function setHasBoundaryGap(bool $value) : ChartDataManager
    {
        $this->hasBoundaryGap = $value;
        return $this;
    }

    public function setIsInverted(bool $value) : ChartDataManager
    {
        $this->isInverted = $value;
        return $this;
    }

    public function setHasDataZoom(bool $value) : ChartDataManager
    {
        $this->hasDataZoom = $value;
        return $this;
    }

    public function setAnimationDuration(int $value) : ChartDataManager
    {
        $this->animationDuration = $value;
        return $this;
    }

    public function setYAxisLabelValueFormat(string $value) : ChartDataManager
    {
        $this->yAxisLabelValueFormat = $value;
        return $this;
    }

    public function setRawData(string $value) : ChartDataManager
    {
        $this->rawData = $value;
        return $this;
    }

    public function setShowPointValues(bool $value) : ChartDataManager
    {
        $this->showPointValues = $value;
        return $this;
    }

    public function setIsStacked(bool $value) : ChartDataManager
    {
        $this->isStacked = $value;
        return $this;
    }

    public function setIsArea(bool $value) : ChartDataManager
    {
        $this->isArea = $value;
        return $this;
    }

    public function setMarkLine(string $value) : ChartDataManager
    {
        $this->markLine = $value;
        return $this;
    }

    public function addCategories($category) : ChartDataManager
    {
        if(is_array($category)) {
            $this->categories = array_merge($this->categories, $category);
        } else {
            $this->categories[] = $category;
        }

        return $this;
    }

    public function addSeries(SeriesData $series) : ChartDataManager
    {
        $this->getSeries()->push($series);
        return $this;
    }

    public function toJson(): string
    {
        return json_encode($this->toArray());
    }

    public function toArray(): array
    {
        $data['series']                 = $this->getSeries()->toArray();
        $data['categories']             = $this->getCategories();
        $data['charts']                 = $this->getNumberOfCharts();
        $data['titles']                 = $this->getTitles();
        $data['colors']                 = $this->getColors();
        $data['boundaryGap']            = $this->getHasBoundaryGap();
        $data['inverted']               = $this->getIsInverted();
        $data['dataZoom']               = $this->getHasDataZoom();
        $data['animationDuration']      = $this->getAnimationDuration();
        $data['yAxisLabelValueFormat']  = $this->getYAxisLabelValueFormat();
        $data['raw']                    = $this->getRawData() == null ? null : json_encode(json_decode($this->getRawData()));

        $data['pointValues']            = $this->getShowPointValues();
        $data['stacked']                = $this->getIsStacked();
        $data['isArea']                 = $this->getIsArea();
        $data['markLine']               = $this->getMarkLine();

        return $data;
    }

}