import * as tslib_1 from "tslib";
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ReactRenderer, ReactWrapper } from "igniteui-react-core/ES5/react-renderer";
import { TypeRegistrar } from "igniteui-react-core/ES5/type";
import { DataChartStylingDefaults } from './DataChartStylingDefaults';
import { XamDoughnutChart } from './XamDoughnutChart';
import { ensureBool, fromPoint, CollectionAdapter, initializePropertiesFromCss, isValidProp, getModifiedProps } from "igniteui-react-core/ES5/componentUtil";
import { Style } from "igniteui-react-core/ES5/Style";
import { SliceClickEventArgs } from "igniteui-react-charts/ES5/igr-slice-click-event-args";
import { HoleDimensionsChangedEventArgs } from "igniteui-react-charts/ES5/igr-hole-dimensions-changed-event-args";
import { RingSeriesBase } from "igniteui-react-charts/ES5/RingSeriesBase";
import { NotifyCollectionChangedAction } from "igniteui-react-core/ES5/NotifyCollectionChangedAction";
import { RingSeriesCollection } from "igniteui-react-charts/ES5/igr-ring-series-collection";
import { DataContext } from "igniteui-react-core/ES5/igr-data-context";
import { delegateCombine, delegateRemove } from "igniteui-react-core/ES5/type";
import { ContentChildrenManager } from "igniteui-react-core/ES5/ContentChildrenManager";
/**
 * Represents concentric circles divided on arcs  depending on data.
*/
var IgrDoughnutChart = /** @class */ (function (_super) {
    tslib_1.__extends(IgrDoughnutChart, _super);
    function IgrDoughnutChart(props) {
        var _this = _super.call(this, props) || this;
        _this._contentChildren = null;
        _this._contentChildrenActual = null;
        _this._contentChildrenMap = null;
        _this._contentChildrenUnresolved = 0;
        _this._hasUserValues = new Set();
        /**
         * The series actually present in the chart. Do not directly modify this array.
         * This array's contents can be modified by causing Angular to reproject the child content.
         * Or adding and removing series from the manual series collection on the series property.
         */
        _this.actualSeries = [];
        _this._seriesAdapter = null;
        _this._series = null;
        _this._defaultTooltips = null;
        _this._uniqueTooltipId = 0;
        _this._initialized = false;
        _this._sliceClick = null;
        _this._sliceClick_wrapped = null;
        _this._holeDimensionsChanged = null;
        _this._holeDimensionsChanged_wrapped = null;
        _this._getMainRef = _this._getMainRef.bind(_this);
        _this._tooltipRef = _this._tooltipRef.bind(_this);
        _this._activeTooltipElements = new Map();
        _this._activeTooltips = new Map();
        _this._currentTooltips = [];
        _this._contentChildrenManager = new ContentChildrenManager(function (ch) { return ch.key || ch.props.name; }, function (ch) { return ch.key || ch.props.name; }, function () { return _this._updateContentChildren(); });
        var container = null;
        if (document) {
            container = document.createElement("div");
            container.style.display = "block";
            container.style.width = "100%";
            container.style.height = "100%";
        }
        var root;
        root = container;
        _this._renderer = new ReactRenderer(root, document, true, DataChartStylingDefaults);
        _this.container = _this._renderer.getWrapper(container);
        _this._implementation = _this.createImplementation();
        _this._implementation.externalObject = _this;
        _this.onImplementationCreated();
        _this._wrapper = _this._renderer;
        var chart = _this.i;
        _this._chart = chart;
        chart.provideContainer(_this._renderer);
        _this._renderer.addSizeWatcher(function () {
            _this._chart.notifyResized();
        });
        return _this;
    }
    Object.defineProperty(IgrDoughnutChart.prototype, "height", {
        get: function () {
            return this._height;
        },
        set: function (value) {
            this._height = value;
            if (this._elRef) {
                this._elRef.style.height = value;
                this._chart.notifyResized();
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "width", {
        get: function () {
            return this._width;
        },
        set: function (value) {
            this._width = value;
            if (this._elRef) {
                this._elRef.style.width = value;
                this._chart.notifyResized();
            }
        },
        enumerable: true,
        configurable: true
    });
    IgrDoughnutChart.prototype._updateContentChildren = function () {
        this.contentSeries = [];
        var contentChildrenActual = this._contentChildrenManager.contentChildrenActual;
        for (var i = 0; i < contentChildrenActual.length; i++) {
            if ((RingSeriesBase.$type).isAssignableFrom(contentChildrenActual[i].i.$type)) {
                this.contentSeries.push(contentChildrenActual[i]);
            }
        }
        if (this._seriesAdapter !== null) {
            this._seriesAdapter.notifyContentChanged();
        }
    };
    IgrDoughnutChart.prototype._tooltipRef = function (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);
    };
    IgrDoughnutChart.prototype.render = function () {
        // if (!this._childrenDiffer(this.props.children)) {
        // 	let div = React.createElement("div", {
        // 		ref: (ref) => {
        // 			this._elRef = ref;
        // 		},
        // 		children: this.props.children
        // 	});
        // 	return div;
        // } else {
        var children = this._contentChildrenManager.getChildren(this.props.children);
        if (this._currentTooltips && this._currentTooltips.length > 0) {
            for (var i = 0; i < this._currentTooltips.length; i++) {
                var t = this._currentTooltips[i];
                if (this._activeTooltipElements.has(t)) {
                    children.push(this._activeTooltipElements.get(t));
                }
                else {
                    if (!TypeRegistrar.isRegistered("IgrTooltipContainer")) {
                        continue;
                    }
                    var Tooltip = TypeRegistrar.get("IgrTooltipContainer");
                    var tEle = React.createElement(Tooltip, {
                        ref: this._tooltipRef,
                        key: this._currentTooltips[i].key,
                        owner: this._currentTooltips[i]
                    });
                    var portal = ReactDOM.createPortal(tEle, t, this._currentTooltips[i].key);
                    this._activeTooltipElements.set(t, portal);
                    children.push(portal);
                }
            }
        }
        var div = React.createElement("div", {
            ref: this._getMainRef,
            children: children
        });
        return div;
        //}
    };
    Object.defineProperty(IgrDoughnutChart.prototype, "hasUserValues", {
        get: function () {
            {
                return this._hasUserValues;
            }
        },
        enumerable: true,
        configurable: true
    });
    IgrDoughnutChart.prototype.componentDidMount = function () {
        var e_1, _a;
        try {
            for (var _b = tslib_1.__values(Object.keys(this.props)), _c = _b.next(); !_c.done; _c = _b.next()) {
                var p = _c.value;
                if (isValidProp(this, p)) {
                    {
                        this._hasUserValues.add(p);
                        this[p] = this.props[p];
                    }
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
            }
            finally { if (e_1) throw e_1.error; }
        }
        this._elRef.style.width = this._width ? this._width : "";
        this._elRef.style.height = this._height ? this._height : "";
        this._elRef.appendChild(this.container.getNativeElement());
        this._chart.notifyResized();
        this.initializeContent();
    };
    IgrDoughnutChart.prototype.shouldComponentUpdate = function (nextProps, nextState) {
        var e_2, _a;
        var mod = getModifiedProps(this.props, nextProps);
        try {
            for (var _b = tslib_1.__values(Object.keys(mod)), _c = _b.next(); !_c.done; _c = _b.next()) {
                var p = _c.value;
                if (isValidProp(this, p)) {
                    this._hasUserValues.add(p);
                    this[p] = mod[p];
                }
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
            }
            finally { if (e_2) throw e_2.error; }
        }
        return true;
    };
    IgrDoughnutChart.prototype._getMainRef = function (div) {
        this._elRef = div;
    };
    IgrDoughnutChart.prototype.destroy = function () {
        this._chart.destroy();
        this._wrapper.destroy();
    };
    IgrDoughnutChart.prototype.initializeContent = function () {
        var _this = this;
        initializePropertiesFromCss(this.container.getNativeElement(), this, "doughnut-chart-", this.hasUserValues);
        this._updateContentChildren();
        this._seriesAdapter = new CollectionAdapter(this.contentSeries, this.i.series, this.actualSeries, function (c) { return c.i; }, function (i) {
            i.owner = _this;
            // (<any>i)._provideRenderer(this._dataSource);
            _this._ensureDefaultTooltip(i);
            _this._ensureTooltipCreated(i);
            //(<any>i)._provideRenderer(this._wrapper); 
        }, function (i) {
            //(<any>i)._provideRenderer(null);
        });
        this.i.notifyResized();
    };
    IgrDoughnutChart.prototype.componentWillUnmount = function () {
        //this._grid.destroy();
        this.destroy();
    };
    IgrDoughnutChart.prototype.onImplementationCreated = function () {
    };
    IgrDoughnutChart.prototype.createImplementation = function () {
        return new XamDoughnutChart();
    };
    Object.defineProperty(IgrDoughnutChart.prototype, "i", {
        get: function () {
            return this._implementation;
        },
        enumerable: true,
        configurable: true
    });
    IgrDoughnutChart.prototype.createSeriesComponent = function (type) {
        if (TypeRegistrar.isRegistered(type)) {
            var 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);
        }
    };
    Object.defineProperty(IgrDoughnutChart.prototype, "series", {
        /**
         * A collection or manually added series for the chart.
        */
        get: function () {
            var _this = this;
            if (this._series === null) {
                var coll = new RingSeriesCollection();
                var inner = coll._innerColl;
                inner.addListener(function (sender, e) {
                    switch (e.action) {
                        case NotifyCollectionChangedAction.Add:
                            _this._seriesAdapter.addManualItem(e.newItems.item(0));
                            break;
                        case NotifyCollectionChangedAction.Remove:
                            _this._seriesAdapter.removeManualItemAt(e.oldStartingIndex);
                            break;
                        case NotifyCollectionChangedAction.Replace:
                            _this._seriesAdapter.removeManualItemAt(e.oldStartingIndex);
                            _this._seriesAdapter.insertManualItem(e.newStartingIndex, e.newItems.item(0));
                            break;
                        case NotifyCollectionChangedAction.Reset:
                            _this._seriesAdapter.clearManualItems();
                            break;
                    }
                });
                this._series = coll;
            }
            return this._series;
        },
        enumerable: true,
        configurable: true
    });
    IgrDoughnutChart.prototype._ensureTooltipCreated = function (series) {
        if (series.i.toolTip == null) {
            var tooltip = this.createTooltip();
            var ele = tooltip;
            if (tooltip == null) {
                return;
            }
            series._tooltipContent = tooltip;
            //(<any>tooltip.instance).template = this._tooltipTemplate;
            series.i.toolTip = this.createWrapper(tooltip);
            if (this._activeTooltips.has(ele)) {
                var tCont = this._activeTooltips.get(ele);
                tCont.template = ele.tooltipTemplate;
            }
        }
    };
    IgrDoughnutChart.prototype.createWrapper = function (ele) {
        var wrapper = new ReactWrapper(ele, this._wrapper);
        wrapper.updateToolTip = ele.updateToolTip;
        wrapper.hideToolTip = ele.hideToolTip;
        if (this._activeTooltips.has(ele)) {
            var tCont = this._activeTooltips.get(ele);
            tCont.template = ele.tooltipTemplate;
        }
        return wrapper;
    };
    IgrDoughnutChart.prototype._ensureDefaultTooltip = function (series) {
        if (this._defaultTooltips == null) {
            return;
        }
        this._defaultTooltips.instance["ensureDefaultTooltip"](series);
    };
    IgrDoughnutChart.prototype._onDefaultTooltipsReady = function (cr) {
        if (this.actualSeries && this.actualSeries.length > 0) {
            var currSeries = this.actualSeries;
            for (var i = 0; i < currSeries.length; i++) {
                if (currSeries[i].showDefaultTooltip) {
                    this._ensureDefaultTooltip(currSeries[i]);
                }
            }
        }
    };
    IgrDoughnutChart.prototype.createTooltip = function () {
        var wrapper = this._wrapper.createElement("div");
        var 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);
        var self = this;
        ele.updateToolTip = function (c, isSubContent) {
            if (c.externalObject) {
                c = c.externalObject;
            }
            else {
                var ext = new DataContext();
                ext._implementation = c;
                c = ext;
            }
            if (!isSubContent) {
                if (ele.parentElement != self.container.getNativeElement()) {
                    if (ele.parentElement != null) {
                        ele.parentElement.removeChild(ele);
                    }
                    self.container.getNativeElement().appendChild(ele);
                }
            }
            else {
                c.isSubContent = true;
            }
            if (self._activeTooltips.has(ele)) {
                var 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;
    };
    IgrDoughnutChart.prototype._updateTooltipState = function () {
        if (this._initialized) {
            this.setState({ tooltips: this._currentTooltips });
        }
    };
    Object.defineProperty(IgrDoughnutChart.prototype, "allowSliceSelection", {
        /**
     * Gets or sets whether the slices can be selected.
    */
        get: function () {
            return this.i.aw;
        },
        set: function (v) {
            this.i.aw = ensureBool(v);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "isSurfaceInteractionDisabled", {
        /**
         * Gets or sets whether all surface interactions with the plot area should be disabled.
        */
        get: function () {
            return this.i.ax;
        },
        set: function (v) {
            this.i.ax = ensureBool(v);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "allowSliceExplosion", {
        /**
         * Gets or sets whether the slices can be exploded.
        */
        get: function () {
            return this.i.av;
        },
        set: function (v) {
            this.i.av = ensureBool(v);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "innerExtent", {
        /**
         * Gets or sets the inner extent of the doughnut chart. It is percent from the outer ring's radius.
        */
        get: function () {
            return this.i.a3;
        },
        set: function (v) {
            this.i.a3 = +v;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "selectedSliceFill", {
        /**
         * Gets or sets the fill brush.
        */
        get: function () {
            return this.i.ce ? this.i.ce.fill : null;
        },
        set: function (v) {
            this.ensureSelectedStyle();
            this.i.ce.fill = v;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "selectedSliceStroke", {
        /**
         * Gets or sets the stroke brush.
        */
        get: function () {
            return this.i.ce ? this.i.ce.stroke : null;
        },
        set: function (v) {
            this.ensureSelectedStyle();
            this.i.ce.stroke = v;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "selectedSliceStrokeThickness", {
        /**
         * Gets or sets the stroke thickness.
        */
        get: function () {
            return this.i.ce ? this.i.ce.strokeThickness : NaN;
        },
        set: function (v) {
            this.ensureSelectedStyle();
            this.i.ce.strokeThickness = +v;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "selectedSliceOpacity", {
        /**
         * Gets or sets the opacity.
        */
        get: function () {
            return this.i.ce ? this.i.ce.opacity : NaN;
        },
        set: function (v) {
            this.ensureSelectedStyle();
            this.i.ce.opacity = +v;
        },
        enumerable: true,
        configurable: true
    });
    IgrDoughnutChart.prototype.ensureSelectedStyle = function () {
        if (this.i.ce) {
            return;
        }
        this.i.ce = new Style();
    };
    Object.defineProperty(IgrDoughnutChart.prototype, "pixelScalingRatio", {
        /**
         * Gets or sets the scaling value used to affect the pixel density of the control.
         * A higher scaling ratio will produce crisper visuals at the expense of memory.  Lower values will cause the control
         * to appear blurry.
        */
        get: function () {
            return this.i.a4;
        },
        set: function (v) {
            this.i.a4 = +v;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "actualPixelScalingRatio", {
        /**
         * Resolved pixel scaling ratio. Unless explicitly overridden by the IgxDoughnutChart.PixelScalingRatioComponent property,
         * this one returns the default ratio enforced by device. High resolution devices will initialize this property
         * to a higher value.
        */
        get: function () {
            return this.i.a1;
        },
        set: function (v) {
            this.i.a1 = +v;
        },
        enumerable: true,
        configurable: true
    });
    /**
 * Called by the UI framework to provide a UI container for rendering this control.

* @param container  * The UI container element.
*/
    IgrDoughnutChart.prototype.provideContainer = function (container) {
        this.i.provideContainer(container);
    };
    /**
     * Called when the control has been resized.
    
    */
    IgrDoughnutChart.prototype.notifyResized = function () {
        this.i.notifyResized();
    };
    /**
     * Gets the ID of the UI container.
    
    */
    IgrDoughnutChart.prototype.getContainerID = function () {
        var iv = this.i.bd();
        return (iv);
    };
    /**
     * Gets the center coordinates of the doughnut chart's center presenter.
    
    */
    IgrDoughnutChart.prototype.getCenterCoordinates = function () {
        var iv = this.i.cd();
        return fromPoint(iv);
    };
    /**
     * Gets the hole radius of the doughnut chart's center presenter.
    
    */
    IgrDoughnutChart.prototype.getHoleRadius = function () {
        var iv = this.i.a2();
        return (iv);
    };
    /**
     * Use to force the doughnut chart to finish any deferred work before printing or evaluating its visual.
     * This should only be called if the visual of the doughnut chart needs to be synchronously saved or evaluated.
     * Calling this method too often will hinder the performance of the doughnut chart.
    
    */
    IgrDoughnutChart.prototype.flush = function () {
        this.i.bk();
    };
    /**
     * Returns the chart visuals expressed as a serialized string.
    
    */
    IgrDoughnutChart.prototype.exportSerializedVisualData = function () {
        var iv = this.i.bc();
        return (iv);
    };
    IgrDoughnutChart.prototype.notifyInsertItem = function (source_, index, newItem) {
        this.i.bm(source_, index, newItem);
    };
    IgrDoughnutChart.prototype.notifySetItem = function (source_, index, oldItem, newItem) {
        this.i.bp(source_, index, oldItem, newItem);
    };
    /**
     * Used to manually notify the chart that the data source has reset or cleared its items.
    
    */
    IgrDoughnutChart.prototype.notifyClearItems = function (source_) {
        this.i.bl(source_);
    };
    IgrDoughnutChart.prototype.notifyRemoveItem = function (source_, index, oldItem) {
        this.i.bn(source_, index, oldItem);
    };
    Object.defineProperty(IgrDoughnutChart.prototype, "sliceClick", {
        /**
         * Raised when the slice is clicked.
        */
        get: function () {
            return this._sliceClick;
        },
        set: function (ev) {
            var _this = this;
            if (this._sliceClick_wrapped !== null) {
                this.i.sliceClick = delegateRemove(this.i.sliceClick, this._sliceClick_wrapped);
                this._sliceClick_wrapped = null;
                this._sliceClick = null;
            }
            this._sliceClick = ev;
            this._sliceClick_wrapped = function (o, e) {
                var outerArgs = new SliceClickEventArgs();
                outerArgs._provideImplementation(e);
                if (_this.beforeSliceClick) {
                    _this.beforeSliceClick(_this, outerArgs);
                }
                if (_this._sliceClick) {
                    _this._sliceClick(_this, outerArgs);
                }
            };
            this.i.sliceClick = delegateCombine(this.i.sliceClick, this._sliceClick_wrapped);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgrDoughnutChart.prototype, "holeDimensionsChanged", {
        /**
         * Raised when the dimensions (center point or radius) of the doughnut hole change.
        */
        get: function () {
            return this._holeDimensionsChanged;
        },
        set: function (ev) {
            var _this = this;
            if (this._holeDimensionsChanged_wrapped !== null) {
                this.i.holeDimensionsChanged = delegateRemove(this.i.holeDimensionsChanged, this._holeDimensionsChanged_wrapped);
                this._holeDimensionsChanged_wrapped = null;
                this._holeDimensionsChanged = null;
            }
            this._holeDimensionsChanged = ev;
            this._holeDimensionsChanged_wrapped = function (o, e) {
                var outerArgs = new HoleDimensionsChangedEventArgs();
                outerArgs._provideImplementation(e);
                if (_this.beforeHoleDimensionsChanged) {
                    _this.beforeHoleDimensionsChanged(_this, outerArgs);
                }
                if (_this._holeDimensionsChanged) {
                    _this._holeDimensionsChanged(_this, outerArgs);
                }
            };
            this.i.holeDimensionsChanged = delegateCombine(this.i.holeDimensionsChanged, this._holeDimensionsChanged_wrapped);
        },
        enumerable: true,
        configurable: true
    });
    return IgrDoughnutChart;
}(React.Component));
export { IgrDoughnutChart };
