/*global Mediasite*/
window.Mediasite = window.Mediasite || {};
Mediasite.Css = Mediasite.Css || {};

Mediasite.Css.BackgroundPosition = function (left, top) {
    var _left = left;
    var _top = top;

    this.getLeft = function () { return _left; }
    this.getTop = function () { return _top; }

    this.toString = function () {
        return _left.toString() + ' ' + _top.toString();
    }

    this.equals = function (other) {
        return (other) && this.toString() == other.toString();
    }
}
Mediasite.Css.BackgroundPosition.parse = function (cssPosition) {
    var input = cssPosition || '';
    var parts = input.split(/\s+/);

    if (parts.length != 2) {
        parts = ['', ''];
    }

    return new Mediasite.Css.BackgroundPosition(
		Mediasite.Css.Length.parse(parts[0]),
		Mediasite.Css.Length.parse(parts[1]));
}
Mediasite.Css.BackgroundPosition.ofElement = function (element) {
    element = $(element);
    var positionString = element.css('backgroundPosition');
    if (!positionString) {
        return new Mediasite.Css.BackgroundPosition(
            Mediasite.Css.Length.parse(element.css('background-position-x')),
            Mediasite.Css.Length.parse(element.css('background-position-y'))
        );
    }
    return Mediasite.Css.BackgroundPosition.parse(positionString);
},


Mediasite.Css.Length = function (quantity, unit) {

    var _quantity = quantity;
    var _unit = unit;


    this.getQuantity = function () {
        return _quantity;
    }

    this.getUnit = function () {
        return _unit;
    }

    this.toString = function () {
        return '' + _quantity + _unit;
    }

}
Mediasite.Css.Length.parse = function (cssLength) {
    var expression = /^(left|right|top|bottom|center|[-+]?[\d\.]+)(%|px|pt|pc|in|cm|mm|em|ex|)$/i;
    var cssString = cssLength || '';
    var quantity = 0;
    var unit = '';

    var matches = cssString.match(expression) || [];
    if (matches.length > 0) {
        quantity = Number(matches[1]);
        unit = matches[2];
        if (isNaN(quantity)) {
            quantity = matches[1]; // must be a keyword (e.g. 'center')
            unit = '';
        } else if (unit == '') {
            quantity = 0; // a unitless number is meaningless, unless zero.
        }
    }

    return new Mediasite.Css.Length(quantity, unit);
}


// Utility Methods
Mediasite.Css.getCssPropertyName = function(baseName) {
    return Mediasite.Css.PropertyNameUtil.Instance.getPropertyName(baseName);
};


// Support for the utility methods
Mediasite.Css.PropertyNameUtil = function (vendorPrefixes) {
    var _cssPropertyNames = {};
    var _cssPrefixes = vendorPrefixes || ['', '-webkit-', '-khtml-', '-moz-', '-ms-', '-o-'];

    // Always include an empty prefix.
    if (_cssPrefixes.length < 1 || _cssPrefixes[0] !== '') {
        _cssPrefixes.unshift('');
    }


    this.getPropertyName = function (baseName) {
        if (!_cssPropertyNames[baseName]) {

            // cssPrefixes should always begin with an empty prefix, 
            // so that we favor the unprefixed property name.
            var found = null;
            var i;
            for (i = 0; i < _cssPrefixes.length; i++) {
                var prefix = _cssPrefixes[i];
                if (existsCssProperty(prefix + baseName)) {
                    found = prefix + baseName;
                    if (prefix.length > 0) {
                        // We've determined the vendor prefix for this user agent, 
                        // so shorten candidate set for future searches.
                        _cssPrefixes = ['', prefix];
                    }
                }
            }

            _cssPropertyNames[baseName] = found || baseName;
        }

        return _cssPropertyNames[baseName];
    };


    function existsCssProperty(propertyName) {
        // Normalize property-name and -prefix-property-name to propertyName and PrefixPropertyName
        // (except for Internet Explorer, which uses msPropertyName instead of MsPropertyName)
        propertyName = propertyName.replace(/\-([a-z]{1})/g, function (hyphenText, i) {
            if (i == 0 && hyphenText == '-ms') {
                return hyphenText.substring(1,2);
            }

            return hyphenText.substring(1,2).toUpperCase();
        });


        return (typeof document.documentElement.style[propertyName] == 'string');
    }
};
Mediasite.Css.PropertyNameUtil.Instance = new Mediasite.Css.PropertyNameUtil();


Mediasite.Css.LoadStyleSheets = function (stylesheets, successCallback, errorCallback) {
    var deferredAllStylesheets = $.Deferred();
    deferredAllStylesheets.done(function () {
        if (successCallback) {
            successCallback();
        }
    }).fail(function (stylesheets) {
        if (errorCallback) {
            errorCallback(stylesheets);
        }
    });


    if (!stylesheets || stylesheets.length == 0) {
        deferredAllStylesheets.resolve();
    } else {

        var allStyleSheets = $.map(stylesheets, function (stylesheetUrl) {
            return new StyleSheet(stylesheetUrl);
        });


        var deferreds = $.map(allStyleSheets, function (styleSheet) {
            var deferred = styleSheet.Load();
            return deferred;
        });

        $.whenAll(deferreds)
            .done(function () {
                deferredAllStylesheets.resolve();
            })
            .fail(function (results) {
                var stylesheets = $.map(results, function (element) { return element; }); // flatten
                deferredAllStylesheets.reject(stylesheets);
            });
    }


    function StyleSheet(stylesheetUrl) {
        var deferred;

        var styleSheetElement;
        var self = this;


        this.Load = function () {
            deferred = $.Deferred();

            styleSheetElement = createStyleSheetLink(stylesheetUrl);
            styleSheetElement.on("error", function () {
                clearTimeout(loadTimeout);
                deferred.reject(stylesheetUrl);
            });
            waitForCssToLoad();
            return deferred;
        };

        var loadTimeout;
        var cssFailureCount = 0;
        function waitForCssToLoad() {
            var cssLoaded = isCssLoaded(styleSheetElement);

            if (cssLoaded) {
                deferred.resolve(stylesheetUrl);

            } else if (cssFailureCount > 50) {
                deferred.reject(stylesheetUrl);
            } else {
                cssFailureCount++;
                clearTimeout(loadTimeout);
                loadTimeout = setTimeout(waitForCssToLoad, 100);
            }
        };

        function isCssLoaded(styleSheetElement) {
            var link = styleSheetElement[0];
            var cssLoaded = false;
            if (link) {
                try {
                    if (Mediasite.BrowserDetect.Local() && link.sheet) {
                        cssLoaded = true;
                    } else if (link.sheet && link.sheet.cssRules) {
                        cssLoaded = true;
                    } else if (link.styleSheet && link.styleSheet.cssText && link.styleSheet.cssText.length > 0) {
                        cssLoaded = true;
                    } else if (link.innerHTML && link.innerHTML.length > 0) {
                        cssLoaded = true;
                    }
                }
                catch (ex) { }
            } else {
                // If there aren't any stylesheets to load, then consider them loaded
                cssLoaded = true;
            }

            return cssLoaded;
        }

        function createStyleSheetLink(stylesheetUrl) {
            var tag = document.createElement('link');
            var styleTag = $('<link rel="stylesheet" type="text/css" />');
            styleTag.appendTo('head');
            styleTag.attr('href', stylesheetUrl);

            return styleTag;
        };
    }

}

