/*
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 { Brush } from './Brush';
import { Size } from './Size';
import { Rect } from './Rect';
import { BrushCollection } from './BrushCollection';
import { PointUtil } from './type';
import { EnumUtil, typeGetValue } from './type';
import { stringEndsWith } from './string';
export function brushToString(v) {
    if (v == null) {
        return null;
    }
    return v.fill;
}
export function stringToBrush(v) {
    if (v == null) {
        return null;
    }
    let brush = Brush.create(v);
    return brush;
}
export function ensureEnum($t, v) {
    if (v == null) {
        return 0;
    }
    if (typeof v == "number") {
        return v;
    }
    let ret = typeGetValue(EnumUtil.parse($t, v, true));
    return ret;
}
export function enumToString($t, v) {
    return EnumUtil.toString($t, v);
}
export function ensureBool(v) {
    if (v == null) {
        return false;
    }
    if (typeof v == "boolean") {
        return v;
    }
    return v.toString().toLowerCase() == "true";
}
export function colorToString(v) {
    if (v == null) {
        return null;
    }
    return v.colorString;
}
export function stringToColor(v) {
    if (v == null) {
        return null;
    }
    let brush = Brush.create(v);
    return brush.color;
}
export function fromSize(v) {
    if (v == null) {
        return null;
    }
    return {
        width: v.width,
        height: v.height
    };
}
export function sizeToString(v) {
    if (!v) {
        return null;
    }
    return v.width + " " + v.height;
}
export function toSize(v) {
    if (v == null) {
        return Size.empty;
    }
    let size = null;
    if (typeof v == "string") {
        v = v.trim();
        let parts = v.split(" ");
        if (parts.length != 2) {
            parts = v.split(",");
        }
        if (parts.length != 2) {
            return Size.empty;
        }
        parts[0] = parts[0].trim();
        parts[1] = parts[1].trim();
        let width = parseFloat(parts[0]);
        let height = parseFloat(parts[1]);
        return new Size(0, width, height);
    }
    else {
        if (v != null) {
            size = new Size(0, v.width, v.height);
        }
    }
    return size;
}
export function fromPoint(v) {
    return v;
}
export function pointToString(v) {
    if (!v) {
        return null;
    }
    return v.x + " " + v.y;
}
export function toPoint(v) {
    if (v == null) {
        return PointUtil.createXY(NaN, NaN);
    }
    let point = null;
    if (typeof v == "string") {
        v = v.trim();
        let parts = v.split(" ");
        if (parts.length != 2) {
            parts = v.split(",");
        }
        if (parts.length != 2) {
            return PointUtil.createXY(NaN, NaN);
        }
        parts[0] = parts[0].trim();
        parts[1] = parts[1].trim();
        let x = parseFloat(parts[0]);
        let y = parseFloat(parts[1]);
        return PointUtil.createXY(x, y);
    }
    else {
        if (v != null) {
            point = PointUtil.createXY(v.x, v.y);
        }
    }
    return point;
}
export function fromRect(v) {
    if (v == null) {
        return null;
    }
    return {
        top: v.top,
        left: v.left,
        width: v.width,
        height: v.height
    };
}
export function rectToString(v) {
    if (!v) {
        return null;
    }
    return v.left + " " + v.top + " " + v.width + " " + v.height;
}
export function toRect(v) {
    if (v == null) {
        return Rect.empty;
    }
    let size = null;
    if (typeof v == "string") {
        let parts = v.split(" ");
        if (parts.length != 4) {
            parts = v.split(",");
        }
        if (parts.length != 4) {
            return Rect.empty;
        }
        parts[0] = parts[0].trim();
        parts[1] = parts[1].trim();
        parts[2] = parts[2].trim();
        parts[3] = parts[4].trim();
        let left = parseFloat(parts[0]);
        let top = parseFloat(parts[1]);
        let width = parseFloat(parts[2]);
        let height = parseFloat(parts[3]);
        return new Rect(0, left, top, width, height);
    }
    else {
        if (v != null) {
            size = new Rect(0, v.left, v.top, v.width, v.height);
        }
    }
    return size;
}
export function brushCollectionToString(v) {
    let bArray = fromBrushCollection(v);
    if (bArray == null) {
        return null;
    }
    return bArray.join(" ");
}
export function toBrushCollection(v) {
    if (v == null) {
        return null;
    }
    let isRGB = true;
    if (typeof v == "string") {
        v = v.trim();
        v = v.split(/[\s,]+(?![^(]*\))/gm);
        for (let i = 0; i < v.length; i++) {
            v[i] = v[i].trim();
        }
    }
    let val = v ? v[0] : null;
    if (typeof val == 'string' && val == 'HSV' || val == 'RGB') {
        if (v[0] == 'HSV') {
            isRGB = false;
        }
        v = v.slice(1);
    }
    let brushCollection = new BrushCollection();
    for (var i = 0; v && i < v.length; i++) {
        let brush = Brush.create(v[i]);
        brushCollection.add(brush);
    }
    return brushCollection;
}
export function fromBrushCollection(v) {
    if (v == null) {
        return null;
    }
    let internalCollection = v;
    let ret = [];
    for (let i = 0; i < internalCollection.count; i++) {
        ret.push(internalCollection.item(i).fill);
    }
    return ret;
}
export class CollectionAdapter {
    constructor(query, target, allList, toTarget, onItemAdded, onItemRemoved) {
        this._manualItems = [];
        this._query = query;
        this._target = target;
        this._toTarget = toTarget;
        this._allList = allList;
        this._onItemAdded = onItemAdded;
        this._onItemRemoved = onItemRemoved;
        this.syncItems();
        if (this._query.changes) {
            this._query.changes.subscribe(this.onQueryChanged);
        }
    }
    syncItems() {
        let targetMap = new Map();
        let queryMap = new Map();
        let manualMap = new Map();
        let item = null;
        for (var i = 0; i < this._allList.length; i++) {
            item = this._allList[i];
            targetMap.set(item, true);
        }
        let queryArray = null;
        if (this._query.toArray) {
            queryArray = this._query.toArray();
        }
        else {
            queryArray = this._query;
        }
        for (var i = 0; i < queryArray.length; i++) {
            item = queryArray[i];
            queryMap.set(item, true);
        }
        for (var i = 0; i < this._manualItems.length; i++) {
            item = this._manualItems[i];
            manualMap.set(item, true);
        }
        for (var i = this._allList.length - 1; i >= 0; i--) {
            item = this._allList[i];
            if (!queryMap.has(item) && !manualMap.has(item)) {
                this._allList.splice(i, 1);
                this._target.removeAt(i);
                this._onItemRemoved(item);
            }
        }
        let ind = 0;
        let ins = 0;
        let insItem = null;
        let maxLen = queryArray.length + this._manualItems.length;
        while (ind < maxLen) {
            if (ind < queryArray.length) {
                insItem = queryArray[ind];
            }
            else if ((ind - queryArray.length) < this._manualItems.length) {
                insItem = this._manualItems[ind - queryArray.length];
            }
            else {
                break;
            }
            if (ins < this._allList.length) {
                item = this._allList[ins];
                if (item === insItem) {
                    ins++;
                    ind++;
                }
                else {
                    this._allList.splice(ins, 0, insItem);
                    this._target.insert(ins, this._toTarget(insItem));
                    this._onItemAdded(insItem);
                    ind++;
                    ins++;
                }
            }
            else {
                this._allList.push(insItem);
                this._target.add(this._toTarget(insItem));
                this._onItemAdded(insItem);
                ind++;
                ins++;
            }
        }
    }
    notifyContentChanged() {
        this.onQueryChanged(this._query);
    }
    onQueryChanged(currentItems) {
        this.syncItems();
    }
    addManualItem(item) {
        this._manualItems.push(item);
        this.syncItems();
    }
    removeManualItem(item) {
        let ind = this._manualItems.indexOf(item);
        if (ind >= 0) {
            this._manualItems.splice(ind, 1);
            this.syncItems();
            return true;
        }
        return false;
    }
    removeManualItemAt(index) {
        this._manualItems.splice(index, 1);
        this.syncItems();
    }
    clearManualItems() {
        this._manualItems.length = 0;
        this.syncItems();
    }
    insertManualItem(index, item) {
        this._manualItems.splice(index, 0, item);
        this.syncItems();
    }
}
export function addPaletteThemeEntry(theme, clss, background, border, foreground) {
    if (theme[clss] === undefined) {
        theme[clss] = {};
    }
    if (background !== null) {
        theme[clss]["background-color"] = background;
    }
    if (border !== null && border !== undefined) {
        theme[clss]["border-top-color"] = border;
        theme[clss]["border-left-color"] = border;
        theme[clss]["border-right-color"] = border;
        theme[clss]["border-bottom-color"] = border;
    }
    if (foreground !== null && foreground !== undefined) {
        theme[clss]["color"] = foreground;
    }
}
export function addTextThemeEntry(theme, clss, fontFamily, fontSize, textColor, leftMargin, topMargin, rightMargin, bottomMargin, horizontalAlignment, verticalAlignment) {
    if (theme[clss] === undefined) {
        theme[clss] = {};
    }
    let t = theme[clss];
    if (fontFamily !== null && fontFamily !== undefined) {
        t["font-family"] = fontFamily;
        t["font-weight"] = "";
        t["font-style"] = "";
        t["font-variant"] = "";
        t["line-height"] = "";
    }
    if (fontSize !== null && fontSize !== undefined) {
        t["font-size"] = fontSize;
        t["font-weight"] = "";
        t["font-style"] = "";
        t["font-variant"] = "";
        t["line-height"] = "";
    }
    if (textColor !== null && textColor !== undefined) {
        t["color"] = textColor;
    }
    if (leftMargin !== null && leftMargin !== undefined) {
        t["margin-left"] = leftMargin;
    }
    if (topMargin !== null && topMargin !== undefined) {
        t["margin-top"] = topMargin;
    }
    if (rightMargin !== null && rightMargin !== undefined) {
        t["margin-right"] = rightMargin;
    }
    if (bottomMargin !== null && bottomMargin !== undefined) {
        t["margin-bottom"] = bottomMargin;
    }
    if (horizontalAlignment !== null && horizontalAlignment !== undefined) {
        t["text-align"] = horizontalAlignment;
    }
    if (verticalAlignment !== null && verticalAlignment !== undefined) {
        t["vertical-align"] = verticalAlignment;
    }
}
function isStylableProperty(name) {
    // using lower case to prevent issGrues with matching case of properties (e.g. chart.brushes)
    let propName = name.toLowerCase();
    // skip non-stylable properties
    if (propName == "height" ||
        propName == "width") {
        return false;
    }
    // check for all stylable properties
    if (stringEndsWith(propName, "height") || // grid.rowHeight
        // grid.rowHeight
        stringEndsWith(propName, "width") || // zoomSlider.HigherThumbWidth
        // zoomSlider.HigherThumbWidth
        stringEndsWith(propName, "width") || // zoomSlider.HigherCalloutOutline
        // zoomSlider.HigherCalloutOutline
        stringEndsWith(propName, "inset") || // zoomSlider.EndInset
        // zoomSlider.EndInset
        stringEndsWith(propName, "orientation") || // zoomSlider.Orientation
        // zoomSlider.Orientation
        stringEndsWith(propName, "duration") || // zoomSlider.PanTransitionDuration
        // zoomSlider.PanTransitionDuration
        stringEndsWith(propName, "outline") || // zoomSlider.BarOutline
        // zoomSlider.BarOutline
        stringEndsWith(propName, "brush") ||
        stringEndsWith(propName, "background") ||
        stringEndsWith(propName, "opacity") ||
        stringEndsWith(propName, "textstyle") ||
        stringEndsWith(propName, "brushes") || // chart.brushes  || chart.negativeBrushes
        // chart.brushes  || chart.negativeBrushes
        stringEndsWith(propName, "outlines") || // chart.outlines || chart.negativeOutlines
        // chart.outlines || chart.negativeOutlines
        stringEndsWith(propName, "thickness") || // chart.AxisStrokeThickness
        // chart.AxisStrokeThickness
        stringEndsWith(propName, "colors") || //
        //
        stringEndsWith(propName, "color") || // chart.AxisLabelTextColor
        // chart.AxisLabelTextColor
        stringEndsWith(propName, "margin") || // chart.AxisLabelTopMargin
        // chart.AxisLabelTopMargin
        stringEndsWith(propName, "location") || // chart.AxisLabelLocation
        // chart.AxisLabelLocation
        stringEndsWith(propName, "style") || // chart.AxisLabelTextStyle
        // chart.AxisLabelTextStyle
        stringEndsWith(propName, "alignment") || // chart.AxisLabelHorizontalAlignment
        // chart.AxisLabelHorizontalAlignment
        stringEndsWith(propName, "visibility") || // chart.AxisLabelVisibility
        // chart.AxisLabelVisibility
        stringEndsWith(propName, "extent") || // chart.AxisExtent
        // chart.AxisExtent
        stringEndsWith(propName, "length") || // chart.AxisTickLength
        // chart.AxisTickLength
        stringEndsWith(propName, "strip") || // chart.AxisStrip
        // chart.AxisStrip
        stringEndsWith(propName, "stroke") || // chart.AxisStroke
        // chart.AxisStroke
        stringEndsWith(propName, "visible")) {
        // chart.isToolbarVisible
        return true;
    }
    return false;
}
function resolveUnits(val) {
    // TODO convert "em, px, pt, cm, in" units to "px"?
    // https://www.w3.org/Style/Examples/007/units.en.html
    let value = val.toLowerCase();
    if (stringEndsWith(value, "px")) {
        // 20px
        value = value.replace("px", "");
        value = value.replace(" ", "");
    }
    return value;
}
export function toSpinal(value) {
    if (value == null) {
        return null;
    }
    let output = [];
    let upperRun = 0;
    for (let i = 0; i < value.length; i++) {
        var curr = value[i];
        var upperChar = curr.toUpperCase();
        var lowerChar = curr.toLowerCase();
        let charIsNewWord = (upperRun == 0 && output.length > 0);
        let previousCharWasNewWord = (upperRun > 1);
        if (upperChar == curr) {
            if (charIsNewWord) {
                output.push('-');
            }
            upperRun++;
        }
        else if (lowerChar == curr) {
            if (previousCharWasNewWord) {
                output.splice(output.length - 1, 0, '-');
            }
            upperRun = 0;
        }
        else {
            upperRun = 0;
        }
        output.push(lowerChar);
    }
    let sb = "";
    for (let i = 0; i < output.length; i++) {
        sb += output[i];
    }
    return sb;
}
export function fromSpinal(value) {
    if (value == null) {
        return value;
    }
    let parts = value.split('-');
    for (let j = 1; j < parts.length; j++) {
        parts[j] = parts[j].substr(0, 1).toUpperCase() + parts[j].substr(1);
    }
    let ret = "";
    for (let j = 0; j < parts.length; j++) {
        ret += parts[j];
    }
    return ret;
}
function toCssPropertyName(value) {
    let sb = toSpinal(value);
    return sb;
}
// get all property names for specified component and its base classes
export function getAllPropertyNames(comp) {
    let members = [];
    while (comp = (comp.prototype || Object.getPrototypeOf(comp))) {
        if (comp == HTMLElement.prototype) {
            break;
        }
        let props = Object.getOwnPropertyNames(comp.constructor.prototype);
        for (let i = 0; i < props.length; i++) {
            members.push(props[i]);
        }
    }
    return members;
}
export function initializePropertiesFromCss(ele, comp, cssPrefix, ignoredProperties) {
    let styles = getComputedStyle(ele);
    let props = getAllPropertyNames(comp);
    let compName = comp.constructor.name;
    for (let prop of props) {
        if (ignoredProperties && ignoredProperties.has(prop)) {
            continue;
        }
        if (isStylableProperty(prop)) {
            let cssName = toCssPropertyName(prop);
            // check if custom property is set with a prefix
            let cssValue = styles.getPropertyValue("--" + cssPrefix + cssName);
            if (cssValue && cssValue.length && cssValue.length > 0) {
                comp[prop] = resolveUnits(cssValue.trim());
            }
            // check if custom property is set without a prefix
            cssValue = styles.getPropertyValue("--" + cssName);
            if (cssValue && cssValue.length && cssValue.length > 0) {
                comp[prop] = resolveUnits(cssValue.trim());
            }
        }
    }
}
export function addBrushPaletteThemeEntry(theme, clss, backgrounds, outlines) {
    if (outlines == null) {
        outlines = backgrounds;
    }
    let t = theme;
    for (let i = 0; i < Math.max(backgrounds.length, outlines.length); i++) {
        let pName = clss + "-" + (i + 1);
        if (t[pName] === undefined) {
            t[pName] = {};
        }
        if (backgrounds[i] !== undefined) {
            t[pName]["background-color"] = backgrounds[i];
        }
        if (outlines[i] !== undefined) {
            t[pName]["border-top-color"] = outlines[i];
            t[pName]["border-left-color"] = outlines[i];
            t[pName]["border-right-color"] = outlines[i];
            t[pName]["border-bottom-color"] = outlines[i];
        }
    }
}
//# sourceMappingURL=componentUtil.js.map