import * as tslib_1 from "tslib";
import { Component, ChangeDetectionStrategy, ViewChild, ViewContainerRef, Input, NgZone, ComponentFactoryResolver, Renderer2, Injector, EventEmitter, Output, ContentChildren, QueryList } from '@angular/core';
import { AngularRenderer, AngularWrapper } from "igniteui-angular-core";
import { TypeRegistrar, delegateCombine } from "igniteui-angular-core";
import { DataChartStylingDefaults } from './DataChartStylingDefaults';
import { XamDoughnutChart } from './XamDoughnutChart';
import { ensureBool, fromPoint, CollectionAdapter, toSpinal, initializePropertiesFromCss, NamePatcher } from "igniteui-angular-core";
import { Style } from "igniteui-angular-core";
import { IgxSliceClickEventArgs } from "./igx-slice-click-event-args";
import { IgxHoleDimensionsChangedEventArgs } from "./igx-hole-dimensions-changed-event-args";
import { IgxRingSeriesBaseComponent } from "./igx-ring-series-base-component";
import { NotifyCollectionChangedAction } from "igniteui-angular-core";
import { IgxRingSeriesCollection } from "./igx-ring-series-collection";
import { IgxPieSliceDataContext } from "./igx-pie-slice-data-context";
export const IgxDoughnutChartComponent_PROVIDERS = [];
/**
 * Represents concentric circles divided on arcs  depending on data.
*/
let IgxDoughnutChartComponent = class IgxDoughnutChartComponent {
    constructor(renderer, _elRef, ngZone, injector, componentFactoryResolver) {
        this.renderer = renderer;
        this._elRef = _elRef;
        this.ngZone = ngZone;
        this.injector = injector;
        this.componentFactoryResolver = componentFactoryResolver;
        /**
         * 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.__p = null;
        this._hasUserValues = new Set();
        this._stylingContainer = null;
        this._stylingParent = null;
        this._inStyling = false;
        this._sliceClick = null;
        this._holeDimensionsChanged = null;
        this._zoneRunner = null;
        if (this._styling) {
            NamePatcher.ensureStylablePatched(Object.getPrototypeOf(this));
        }
        this._implementation = this.createImplementation();
        this._implementation.externalObject = this;
        this.onImplementationCreated();
        this._zoneRunner = (act) => ngZone.run(act);
        this.container = renderer.createElement("div");
        renderer.appendChild(_elRef.element.nativeElement, this.container);
        renderer.setStyle(this.container, "display", "block");
        renderer.setStyle(this.container, "width", "100%");
        renderer.setStyle(this.container, "height", "100%");
        var root;
        root = this.container;
        if (this.container != null) {
            root = this.container;
        }
        var ren = new AngularRenderer(root, this.renderer, window.document, this.ngZone, true, DataChartStylingDefaults);
        this._wrapper = ren;
        var chart = this.i;
        this._chart = chart;
        this._seriesAdapter = new CollectionAdapter([], this.i.series, this.actualSeries, (c) => c.i, (i) => {
            i.owner = this;
            // (<any>i)._provideRenderer(this._dataSource);
            if (this.container && this.container.parentElement) {
                i._styling(this.container, this, this);
            }
            this._ensureDefaultTooltip(i);
            this._ensureTooltipCreated(i);
        }, (i) => {
            //(<any>i)._provideRenderer(null);
        });
        chart.provideContainer(ren);
        ren.addSizeWatcher(() => {
            this._chart.notifyResized();
        });
    }
    set height(value) {
        this._height = value;
        this.renderer.setStyle(this._elRef.element.nativeElement, "height", value);
        this._chart.notifyResized();
    }
    get height() {
        return this._height;
    }
    set width(value) {
        this._width = value;
        this.renderer.setStyle(this._elRef.element.nativeElement, "width", value);
        this._chart.notifyResized();
    }
    get width() {
        return this._width;
    }
    ngOnDestroy() {
        this._chart.destroy();
        this._wrapper.destroy();
    }
    onImplementationCreated() {
    }
    createImplementation() {
        return new XamDoughnutChart();
    }
    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);
        }
    }
    ngAfterContentInit() {
        if (TypeRegistrar.isRegistered("IgxDoughnutChartDefaultTooltipsComponent")) {
            let c = TypeRegistrar.get("IgxDoughnutChartDefaultTooltipsComponent");
            let cf = this.componentFactoryResolver.resolveComponentFactory(c);
            let cr = this._dynamicContent.createComponent(cf);
            this._defaultTooltips = cr;
            cr.instance.onContentReady.subscribe(() => {
                this._onDefaultTooltipsReady(cr);
            });
        }
        this._seriesAdapter.updateQuery(this.contentSeries);
        this._styling(this.container, this);
        if (this.actualSeries && this.actualSeries.length > 0) {
            var currSeries = this.actualSeries;
            for (var i = 0; i < currSeries.length; i++) {
                currSeries[i]._styling(this.container, this, this);
            }
        }
        this.i.notifyResized();
    }
    /**
     * A collection or manually added series for the chart.
    */
    get series() {
        if (this._series === null) {
            let coll = new IgxRingSeriesCollection();
            let inner = coll._innerColl;
            inner.addListener((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;
    }
    _ensureTooltipCreated(series) {
        series._ensureTooltipCreated(() => this.createTooltip(), (ele) => {
            let wrapper = new AngularWrapper(ele, this.renderer, this.ngZone);
            wrapper.updateToolTip = ele.updateToolTip;
            wrapper.hideToolTip = ele.hideToolTip;
            return wrapper;
        });
    }
    _ensureDefaultTooltip(series) {
        if (this._defaultTooltips == null) {
            return;
        }
        this._defaultTooltips.instance["ensureDefaultTooltip"](series);
    }
    _onDefaultTooltipsReady(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]);
                }
            }
        }
    }
    createTooltip() {
        if (!TypeRegistrar.isRegistered("IgxTooltipContainerComponent")) {
            return null;
        }
        let t = TypeRegistrar.get("IgxTooltipContainerComponent");
        let cf = this.componentFactoryResolver.resolveComponentFactory(t);
        let cr = this._dynamicContent.createComponent(cf);
        let ele = cr.location.nativeElement;
        let self = this;
        ele.updateToolTip = function (c) {
            if (c.externalObject) {
                c = c.externalObject;
            }
            else {
                let ext = new IgxPieSliceDataContext();
                ext._implementation = c;
                c = ext;
            }
            if (ele.parentElement != self.container) {
                if (ele.parentElement != null) {
                    ele.parentElement.removeChild(ele);
                }
                self.container.appendChild(ele);
            }
            cr.instance.context = c;
            if (c.series.showDefaultTooltip) {
                var tooltipContainers = ele.getElementsByClassName("ui-tooltip-container");
                if (tooltipContainers.length > 0)
                    tooltipContainers[0].style.borderColor = c.i.slice.background.fill;
            }
            ele.style.display = "block";
            return true;
        };
        ele.hideToolTip = function () {
            ele.style.display = "none";
        };
        ele.style.display = "none";
        return cr;
    }
    /**
 * Gets or sets whether the slices can be selected.
*/
    get allowSliceSelection() {
        return this.i.aw;
    }
    set allowSliceSelection(v) {
        this.i.aw = ensureBool(v);
    }
    /**
     * Gets or sets whether all surface interactions with the plot area should be disabled.
    */
    get isSurfaceInteractionDisabled() {
        return this.i.ax;
    }
    set isSurfaceInteractionDisabled(v) {
        this.i.ax = ensureBool(v);
    }
    /**
     * Gets or sets whether the slices can be exploded.
    */
    get allowSliceExplosion() {
        return this.i.av;
    }
    set allowSliceExplosion(v) {
        this.i.av = ensureBool(v);
    }
    /**
     * Gets or sets the inner extent of the doughnut chart. It is percent from the outer ring's radius.
    */
    get innerExtent() {
        return this.i.a3;
    }
    set innerExtent(v) {
        this.i.a3 = +v;
    }
    /**
     * Gets or sets the fill brush.
    */
    get selectedSliceFill() {
        return this.i.cg ? this.i.cg.fill : null;
    }
    set selectedSliceFill(v) {
        this.ensureSelectedStyle();
        this.i.cg.fill = v;
    }
    /**
     * Gets or sets the stroke brush.
    */
    get selectedSliceStroke() {
        return this.i.cg ? this.i.cg.stroke : null;
    }
    set selectedSliceStroke(v) {
        this.ensureSelectedStyle();
        this.i.cg.stroke = v;
    }
    /**
     * Gets or sets the stroke thickness.
    */
    get selectedSliceStrokeThickness() {
        return this.i.cg ? this.i.cg.strokeThickness : NaN;
    }
    set selectedSliceStrokeThickness(v) {
        this.ensureSelectedStyle();
        this.i.cg.strokeThickness = +v;
    }
    /**
     * Gets or sets the opacity.
    */
    get selectedSliceOpacity() {
        return this.i.cg ? this.i.cg.opacity : NaN;
    }
    set selectedSliceOpacity(v) {
        this.ensureSelectedStyle();
        this.i.cg.opacity = +v;
    }
    ensureSelectedStyle() {
        if (this.i.cg) {
            return;
        }
        this.i.cg = new Style();
    }
    /**
     * 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 pixelScalingRatio() {
        return this.i.a4;
    }
    set pixelScalingRatio(v) {
        this.i.a4 = +v;
    }
    /**
     * 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 actualPixelScalingRatio() {
        return this.i.a1;
    }
    set actualPixelScalingRatio(v) {
        this.i.a1 = +v;
    }
    get hasUserValues() {
        return this._hasUserValues;
    }
    __m(propertyName) {
        if (!this._inStyling) {
            this._hasUserValues.add(propertyName);
        }
    }
    _styling(container, component, parent) {
        if (this._inStyling) {
            return;
        }
        this._inStyling = true;
        this._stylingContainer = container;
        this._stylingParent = component;
        let genericPrefix = "";
        let typeName = this.i.$type.name;
        if (typeName.indexOf("Xam") === 0) {
            typeName = typeName.substring(3);
        }
        genericPrefix = toSpinal("DoughnutChartComponent");
        let additionalPrefixes = [];
        let prefix = toSpinal(typeName);
        additionalPrefixes.push(prefix + "-");
        let b = this.i.$type.baseType;
        while (b && b.name != "Object" &&
            b.name != "Base" &&
            b.name != "Control" &&
            b.Name != "DependencyObject" &&
            b.Name != "FrameworkElement") {
            typeName = b.name;
            if (typeName.indexOf("Xam") === 0) {
                typeName = typeName.substring(3);
            }
            let basePrefix = toSpinal(typeName);
            additionalPrefixes.push(basePrefix + "-");
            b = b.baseType;
        }
        if (parent) {
            let parentTypeName = parent.i.$type.name;
            if (parentTypeName.indexOf("Xam") === 0) {
                parentTypeName = parentTypeName.substring(3);
            }
            let parentPrefix = toSpinal(parentTypeName);
            additionalPrefixes.push(parentPrefix + "-" + genericPrefix + "-");
            additionalPrefixes.push(parentPrefix + "-" + prefix + "-");
        }
        initializePropertiesFromCss(container, this, genericPrefix + "-", this.hasUserValues, false, additionalPrefixes);
        if (this._otherStyling) {
            this._otherStyling(container, component, parent);
        }
        this._inStyling = false;
    }
    /**
 * Called by the UI framework to provide a UI container for rendering this control.

* @param container  * The UI container element.
*/
    provideContainer(container) {
        this.i.provideContainer(container);
    }
    /**
     * Called when the control has been resized.
    
    */
    notifyResized() {
        this.i.notifyResized();
    }
    /**
     * Gets the ID of the UI container.
    
    */
    getContainerID() {
        let iv = this.i.bd();
        return (iv);
    }
    /**
     * Gets the center coordinates of the doughnut chart's center presenter.
    
    */
    getCenterCoordinates() {
        let iv = this.i.cf();
        return fromPoint(iv);
    }
    /**
     * Gets the hole radius of the doughnut chart's center presenter.
    
    */
    getHoleRadius() {
        let 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.
    
    */
    flush() {
        this.i.bk();
    }
    /**
     * Returns the chart visuals expressed as a serialized string.
    
    */
    exportSerializedVisualData() {
        let iv = this.i.bc();
        return (iv);
    }
    notifyInsertItem(source_, index, newItem) {
        this.i.bm(source_, index, newItem);
    }
    notifySetItem(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.
    
    */
    notifyClearItems(source_) {
        this.i.bl(source_);
    }
    notifyRemoveItem(source_, index, oldItem) {
        this.i.bn(source_, index, oldItem);
    }
    /**
     * Raised when the slice is clicked.
    */
    get sliceClick() {
        if (this._sliceClick == null) {
            this._sliceClick = new EventEmitter();
            this.i.sliceClick = delegateCombine(this.i.sliceClick, (o, e) => {
                this._runInZone(() => {
                    let outerArgs = new IgxSliceClickEventArgs();
                    outerArgs._provideImplementation(e);
                    if (this.beforeSliceClick) {
                        this.beforeSliceClick(this, outerArgs);
                    }
                    this._sliceClick.emit({
                        sender: this,
                        args: outerArgs
                    });
                });
            });
        }
        return this._sliceClick;
    }
    /**
     * Raised when the dimensions (center point or radius) of the doughnut hole change.
    */
    get holeDimensionsChanged() {
        if (this._holeDimensionsChanged == null) {
            this._holeDimensionsChanged = new EventEmitter();
            this.i.holeDimensionsChanged = delegateCombine(this.i.holeDimensionsChanged, (o, e) => {
                this._runInZone(() => {
                    let outerArgs = new IgxHoleDimensionsChangedEventArgs();
                    outerArgs._provideImplementation(e);
                    if (this.beforeHoleDimensionsChanged) {
                        this.beforeHoleDimensionsChanged(this, outerArgs);
                    }
                    this._holeDimensionsChanged.emit({
                        sender: this,
                        args: outerArgs
                    });
                });
            });
        }
        return this._holeDimensionsChanged;
    }
    _runInZone(act) {
        if (this._zoneRunner != null) {
            this._zoneRunner(act);
        }
        else {
            act();
        }
    }
};
tslib_1.__decorate([
    ContentChildren(IgxRingSeriesBaseComponent),
    tslib_1.__metadata("design:type", QueryList)
], IgxDoughnutChartComponent.prototype, "contentSeries", void 0);
tslib_1.__decorate([
    ViewChild("dynamicContent", { read: ViewContainerRef, static: true }),
    tslib_1.__metadata("design:type", ViewContainerRef)
], IgxDoughnutChartComponent.prototype, "_dynamicContent", void 0);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", String),
    tslib_1.__metadata("design:paramtypes", [String])
], IgxDoughnutChartComponent.prototype, "height", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", String),
    tslib_1.__metadata("design:paramtypes", [String])
], IgxDoughnutChartComponent.prototype, "width", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Boolean),
    tslib_1.__metadata("design:paramtypes", [Boolean])
], IgxDoughnutChartComponent.prototype, "allowSliceSelection", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Boolean),
    tslib_1.__metadata("design:paramtypes", [Boolean])
], IgxDoughnutChartComponent.prototype, "isSurfaceInteractionDisabled", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Boolean),
    tslib_1.__metadata("design:paramtypes", [Boolean])
], IgxDoughnutChartComponent.prototype, "allowSliceExplosion", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Number),
    tslib_1.__metadata("design:paramtypes", [Number])
], IgxDoughnutChartComponent.prototype, "innerExtent", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", String),
    tslib_1.__metadata("design:paramtypes", [String])
], IgxDoughnutChartComponent.prototype, "selectedSliceFill", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", String),
    tslib_1.__metadata("design:paramtypes", [String])
], IgxDoughnutChartComponent.prototype, "selectedSliceStroke", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Number),
    tslib_1.__metadata("design:paramtypes", [Number])
], IgxDoughnutChartComponent.prototype, "selectedSliceStrokeThickness", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Number),
    tslib_1.__metadata("design:paramtypes", [Number])
], IgxDoughnutChartComponent.prototype, "selectedSliceOpacity", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Number),
    tslib_1.__metadata("design:paramtypes", [Number])
], IgxDoughnutChartComponent.prototype, "pixelScalingRatio", null);
tslib_1.__decorate([
    Input(),
    tslib_1.__metadata("design:type", Number),
    tslib_1.__metadata("design:paramtypes", [Number])
], IgxDoughnutChartComponent.prototype, "actualPixelScalingRatio", null);
tslib_1.__decorate([
    Output(),
    tslib_1.__metadata("design:type", EventEmitter),
    tslib_1.__metadata("design:paramtypes", [])
], IgxDoughnutChartComponent.prototype, "sliceClick", null);
tslib_1.__decorate([
    Output(),
    tslib_1.__metadata("design:type", EventEmitter),
    tslib_1.__metadata("design:paramtypes", [])
], IgxDoughnutChartComponent.prototype, "holeDimensionsChanged", null);
IgxDoughnutChartComponent = tslib_1.__decorate([
    Component({
        selector: 'igx-doughnut-chart',
        template: `<ng-container #dynamicContent></ng-container>`,
        changeDetection: ChangeDetectionStrategy.OnPush,
        providers: IgxDoughnutChartComponent_PROVIDERS,
        host: { 'class': 'ig-doughnut-chart igx-doughnut-chart' },
        styles: [`
		:host {
			display: block;
		}
	`]
    }),
    tslib_1.__metadata("design:paramtypes", [Renderer2,
        ViewContainerRef,
        NgZone,
        Injector,
        ComponentFactoryResolver])
], IgxDoughnutChartComponent);
export { IgxDoughnutChartComponent };
//# sourceMappingURL=igx-doughnut-chart-component.js.map