/*
THIS INFRAGISTICS ULTIMATE SOFTWARE LICENSE  AGREEMENT ("AGREEMENT") LOCATED HERE:
https://www.infragistics.com/legal/license/igultimate-la
https://www.infragistics.com/legal/license/igultimate-eula
GOVERNS THE LICENSING, INSTALLATION AND USE OF INFRAGISTICS SOFTWARE. BY DOWNLOADING AND/OR INSTALLING AND USING INFRAGISTICS SOFTWARE:  you are indicating that you have read and understand this Agreement, and agree to be legally bound by it on behalf of the yourself and your company.
*/
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ReactRenderer, ReactWrapper } from "igniteui-react-core";
import { TypeRegistrar } from "igniteui-react-core";
import { DataPieChart } from './DataPieChart';
import { DataPieChartType_$type } from './DataPieChartType';
import { CategoryTransitionInMode_$type } from './CategoryTransitionInMode';
import { TransitionInSpeedType_$type } from './TransitionInSpeedType';
import { ensureEnum, ensureBool, NamePatcher } from "igniteui-react-core";
import { DataChartStylingDefaults } from './DataChartStylingDefaults';
import { DataSeriesType } from "igniteui-react-core";
import { IgrDataContext } from "igniteui-react-core";
import { IgrProportionalCategoryAngleAxis } from './igr-proportional-category-angle-axis';
import { IgrNumericRadiusAxis } from './igr-numeric-radius-axis';
import { IgrDataPieBaseChart } from './igr-data-pie-base-chart';
/**
 * Represents a DataPie chart control that can plot DataPie data
*/
export class IgrDataPieChart extends IgrDataPieBaseChart {
    set height(value) {
        this._height = value;
        if (this._elRef) {
            this._elRef.style.height = value;
            this._chart.notifyResized();
        }
    }
    get height() {
        return this._height;
    }
    set width(value) {
        this._width = value;
        if (this._elRef) {
            this._elRef.style.width = value;
            this._chart.notifyResized();
        }
    }
    get width() {
        return this._width;
    }
    _tooltipRef(t) {
        //console.log(t);
        if (t === null) {
            return;
        }
        if (t.currentOwner &&
            t.currentOwner.tooltipTemplate) {
            t.template = t.currentOwner.tooltipTemplate;
        }
        this._activeTooltips.set(t.currentOwner, t);
    }
    _getMainRef(ref) {
        this._elRef = ref;
    }
    render() {
        // if (!this._childrenDiffer(this.props.children)) {
        // 	let div = React.createElement("div", {
        // 		ref: (ref) => {
        // 			this._elRef = ref;
        // 		},
        // 		children: this.props.children
        // 	});
        // 	return div;
        // } else {
        let children = [];
        if (this._currentTooltips && this._currentTooltips.length > 0) {
            for (let i = 0; i < this._currentTooltips.length; i++) {
                let t = this._currentTooltips[i];
                if (this._activeTooltipElements.has(t)) {
                    children.push(this._activeTooltipElements.get(t));
                }
                else {
                    if (!TypeRegistrar.isRegistered("IgrTooltipContainer")) {
                        continue;
                    }
                    let Tooltip = TypeRegistrar.get("IgrTooltipContainer");
                    let tEle = React.createElement(Tooltip, {
                        ref: this._tooltipRef,
                        key: this._currentTooltips[i].key,
                        owner: this._currentTooltips[i]
                    });
                    let portal = ReactDOM.createPortal(tEle, t, this._currentTooltips[i].key);
                    this._activeTooltipElements.set(t, portal);
                    children.push(portal);
                }
            }
        }
        let div = React.createElement("div", {
            className: "ig-data-pie-chart igr-data-pie-chart",
            ref: this._getMainRef,
            children: children
        });
        return div;
        //}
    }
    constructor(props) {
        super(props);
        this._dataSource = null;
        this._defaultTooltips = null;
        this._uniqueTooltipId = 0;
        if (this._styling) {
            NamePatcher.ensureStylablePatched(Object.getPrototypeOf(this));
        }
        this._getMainRef = this._getMainRef.bind(this);
        this._tooltipRef = this._tooltipRef.bind(this);
        this._activeTooltipElements = new Map();
        this._activeTooltips = new Map();
        this._currentTooltips = [];
        if (document) {
            this._container = document.createElement("div");
            this._container.style.display = "block";
            this._container.style.width = "100%";
            this._container.style.height = "100%";
        }
        var root;
        root = this._container;
        if (this._container != null) {
            root = this._container;
        }
        var ren = new ReactRenderer(root, document, true, DataChartStylingDefaults);
        this._wrapper = ren;
        var chart = this.i;
        this._chart = chart;
        if (chart.angleAxis) {
            let x = new IgrProportionalCategoryAngleAxis(null);
            x._provideRenderer(ren);
            x._implementation = chart.angleAxis;
            chart.angleAxis.externalObject = x;
        }
        if (chart.valueAxis) {
            let y = new IgrNumericRadiusAxis(null);
            y._provideRenderer(ren);
            y._implementation = chart.valueAxis;
            chart.valueAxis.externalObject = y;
        }
        chart.provideContainer(ren);
        this.bindData();
        chart.notifyResized();
        ren.addSizeWatcher(() => {
            this._chart.notifyResized();
        });
        this._initialized = true;
    }
    componentDidMount() {
        super.componentDidMount();
        this._elRef.style.width = this._width ? this._width : "";
        this._elRef.style.height = this._height ? this._height : "";
        this._elRef.appendChild(this._container);
        this._chart.notifyResized();
        this.initializeContent();
    }
    componentWillUnmount() {
    }
    destroy() {
        this._chart.destroy();
        this._wrapper.destroy();
    }
    createImplementation() {
        return new DataPieChart();
    }
    get i() {
        return this._implementation;
    }
    createSeriesComponent(type) {
        if (TypeRegistrar.isRegistered(type)) {
            let s = TypeRegistrar.create(type);
            s.owner = this;
            s._provideRenderer(this._wrapper);
            return s;
        }
        else {
            //we shouldn't get here, hopefully.
            throw Error("series type not loaded: " + type);
        }
    }
    createSeries(type) {
        switch (type) {
            case DataSeriesType.Pie:
                return this.createSeriesComponent('IgrRadialPieSeries');
            case DataSeriesType.ItemToolTipLayer:
                return this.createSeriesComponent('IgrItemToolTipLayer');
            case DataSeriesType.CategoryToolTipLayer:
                return this.createSeriesComponent('IgrCategoryToolTipLayer');
            case DataSeriesType.CrosshairLayer:
                return this.createSeriesComponent('IgrCrosshairLayer');
            case DataSeriesType.FinalValueLayer:
                return this.createSeriesComponent('IgrFinalValueLayer');
            case DataSeriesType.CalloutLayer:
                return this.createSeriesComponent('IgrCalloutLayer');
            case DataSeriesType.CategoryHighlightLayer:
                return this.createSeriesComponent('IgrCategoryHighlightLayer');
            case DataSeriesType.CategoryItemHighlightLayer:
                return this.createSeriesComponent('IgrCategoryItemHighlightLayer');
            case DataSeriesType.DataToolTipLayer:
                return this.createSeriesComponent('IgrDataToolTipLayer');
            case DataSeriesType.ValueLayer:
                return this.createSeriesComponent('IgrValueLayer');
            default:
                return this.createSeriesComponent('IgrRadialPieSeries');
        }
    }
    set dataSource(value) {
        this._dataSource = value;
        this.bindData();
    }
    get dataSource() {
        return this._dataSource;
    }
    bindData() {
        if (this._chart != null && this._chart !== undefined) {
            this._chart.itemsSource = this._dataSource;
        }
    }
    initializeContent() {
        if (TypeRegistrar.isRegistered("IgrDataChartDefaultTooltips")) {
            let d = TypeRegistrar.create("IgrDataChartDefaultTooltips");
            this._defaultTooltips = d;
            this._onDefaultTooltipsReady(d);
            //this._container.appendChild(cr.location.nativeElement);
        }
        // supports angular themes or custom properties set in CSS 
        this._styling(this._elRef, this);
        this._chart.notifyResized();
    }
    createTooltip() {
        // if (!TypeRegistrar.isRegistered("IgrTooltipContainer")) {
        // 	return null;
        // }
        // let Tooltip = TypeRegistrar.get("IgrTooltipContainer");
        let wrapper = this._wrapper.createElement("div");
        let ele = wrapper.getNativeElement();
        ele.key = "__tooltip_" + this._uniqueTooltipId;
        this._uniqueTooltipId++;
        this._currentTooltips = this._currentTooltips.slice(0);
        this._currentTooltips.push(ele);
        //let element = React.createElement(Tooltip,  );
        //let portal = ReactDOM.createPortal(element, ele);
        let self = this;
        ele.updateToolTip = function (c, isSubContent) {
            if (c.externalObject) {
                c = c.externalObject;
            }
            else {
                let ext = new IgrDataContext();
                ext._implementation = c;
                c = ext;
            }
            if (!isSubContent) {
                if (ele.parentElement != self._container) {
                    if (ele.parentElement != null) {
                        ele.parentElement.removeChild(ele);
                    }
                    self._container.appendChild(ele);
                }
            }
            else {
                c.isSubContent = true;
            }
            if (self._activeTooltips.has(ele)) {
                let t = self._activeTooltips.get(ele);
                if (t.template === null &&
                    ele.tooltipTemplate !== null) {
                    t.template = ele.tooltipTemplate;
                }
                t.dataContext = c;
            }
            ele.style.display = "block";
            return true;
        };
        ele.hideToolTip = function () {
            ele.style.display = "none";
        };
        ele.style.display = "none";
        this._updateTooltipState();
        return ele;
    }
    _ensureTooltipCreated(series) {
        series._ensureTooltipCreated(() => this.createTooltip(), (ele) => {
            let wrapper = new ReactWrapper(ele, this._wrapper);
            wrapper.updateToolTip = ele.updateToolTip;
            wrapper.hideToolTip = ele.hideToolTip;
            if (this._activeTooltips.has(ele)) {
                let tCont = this._activeTooltips.get(ele);
                tCont.template = ele.tooltipTemplate;
            }
            return wrapper;
        });
    }
    _createXAxis() {
        let x = new IgrProportionalCategoryAngleAxis(null);
        x._provideRenderer(this._wrapper);
        return x.i;
    }
    _createYAxis() {
        let y = new IgrNumericRadiusAxis(null);
        y.provideRenderer(this._wrapper);
        return y.i;
    }
    _ensureDefaultTooltip(series) {
        if (this._defaultTooltips == null) {
            return;
        }
        this._defaultTooltips["ensureDefaultTooltip"](series);
    }
    _onDefaultTooltipsReady(cr) {
        if (this.i.dataChart) {
            var currSeries = this.i.dataChart.series;
            for (var i = 0; i < currSeries.count; i++) {
                if (currSeries.item(i).externalObject.showDefaultTooltip) {
                    this._ensureDefaultTooltip(currSeries.item(i).externalObject);
                }
            }
        }
    }
    _updateTooltipState() {
        if (this._initialized) {
            this.setState({ tooltips: this._currentTooltips });
        }
    }
    /**
 * Gets or sets the duration used for animating series plots when the chart is loading into view
*/
    get transitionInDuration() {
        return this.i.akw;
    }
    set transitionInDuration(v) {
        this.i.akw = +v;
    }
    /**
     * Gets or sets the duration used for animating series plots when the series is leaving view
    */
    get transitionOutDuration() {
        return this.i.akx;
    }
    set transitionOutDuration(v) {
        this.i.akx = +v;
    }
    /**
     * Gets or sets the easing function used for animating series plots when the chart is loading into view
     * This can be set to one of the known values "linear" or "cubic," or it can be set to an easing function which takes a single numeric parameter and returns a number.
    */
    get transitionInEasingFunction() {
        return this.i.akq;
    }
    set transitionInEasingFunction(v) {
        this.i.akq = v;
    }
    /**
     * Gets or sets the easing function used for animating series plots when the chart is loading into view
     * This can be set to one of the known values "linear" or "cubic," or it can be set to an easing function which takes a single numeric parameter and returns a number.
    */
    get transitionOutEasingFunction() {
        return this.i.akr;
    }
    set transitionOutEasingFunction(v) {
        this.i.akr = v;
    }
    /**
     * Gets the domain type of this chart
    */
    get domainType() {
        return this.i.cb;
    }
    /**
     * Gets or sets the type of chart series to generate from the data.
    */
    get chartType() {
        return this.i.akl;
    }
    set chartType(v) {
        this.i.akl = ensureEnum(DataPieChartType_$type, v);
    }
    /**
     * Gets or sets whether animation of series plots is enabled when the chart is loading into view
    */
    get isTransitionInEnabled() {
        return this.i.akt;
    }
    set isTransitionInEnabled(v) {
        this.i.akt = ensureBool(v);
    }
    /**
     * Gets or sets the method that determines how to animate series plots when the chart is loading into view
    */
    get transitionInMode() {
        return this.i.akj;
    }
    set transitionInMode(v) {
        this.i.akj = ensureEnum(CategoryTransitionInMode_$type, v);
    }
    /**
     * Gets or sets the arrival speed used for animating series plots when the chart is loading into view
    */
    get transitionInSpeedType() {
        return this.i.akn;
    }
    set transitionInSpeedType(v) {
        this.i.akn = ensureEnum(TransitionInSpeedType_$type, v);
    }
    /**
 * Export serialized visual data.

*/
    exportSerializedVisualData() {
        let iv = this.i.akz();
        return (iv);
    }
}
