/**
 * Управление CSS файлами
 *$Id: cssmanager.js 89 2008-11-18 15:22:22Z aanpilogov $
 */
PuskFramework.cssManager = new function()
{
    var me = this;
    me.registry = {};
    me.head = null;
    me.isIE = false;
    me.uriSuffix = '';
    var pf = PuskFramework;

    /**
     * Загрузить css файл с указанного uri
     *
     * @param {Object} uri путь к файлу
     * @param {Object} instance уникальный идентификатор группы
     * @param {Object} onReadyStateChange callback после загрузки
     */
    me.loadStyle = function(uri, instance, onReadyStateChange)
    {
        registerEntity(uri, instance, 'link', {
            'uri': uri,
            'onReadyStateChange': onReadyStateChange
        });
    };

    /**
     * Зугрузить инлайн стиль
     *
     * @param {Object} style css текст
     * @param {Object} instance уникальный идентификатор группы
     * @param {Object} id уникальный идентификатор стиля
     */
    me.loadInlineStyle = function(style, instance, id)
    {
        if (!id)
        {
            id = 'style_' + Math.round(Math.random(1, 1000) * 999);
        }
        registerEntity(id, instance, 'inline', {
            'style': style,
            'id': id
        });
    };

    /**
     * Выгрузить указанный стиль из документа
     *
     * @param {Object} id уникальный идентификатор
     * @param {Object} instance уникальный идентификатор группы (не выгружает стиль, если другая группа его использует)
     */
    me.releaseStyle = function(id, instance)
    {
        if (me.registry[id])
        {
            var index = pf.arr.indexOf(me.registry[id], instance);
            if (index > 0)
            {
                me.registry[id].splice(index, 1);
            }
            window.setTimeout(function()
            {
                if (me.registry[id] && me.registry[id].length == 1)
                {
                    if (me.isIE)
                    {
                        var importsCount = me.registry[id][0]['object'].parentStyleSheet.imports.length;
                        var uri = (me.registry[id][0]['type'] == 'inline') ? (me.fakeCss + '?' + id) : id;
                        for (var i = 0; i < importsCount; i++)
                        {
                            if (me.registry[id][0]['object'].parentStyleSheet.imports[i]['href'] == uri)
                            {
                                me.registry[id][0]['object'].cssText = '';
                                me.registry[id][0]['object'].parentStyleSheet.removeImport(i);
                                delete (me.registry[id]);
                                break;
                            }
                        }
                    }
                    else
                    {
                        pf.$_(me.registry[id][0]['object']);
                        delete (me.registry[id]);
                    }
                }
            }, 1000);
        }
    };

    /**
     * Выгружает все стили, подгруженные для заданной группы
     *
     * @param {Object} instance идентификатор группы
     */
    me.releaseInstance = function(instance)
    {
        for (var id in me.registry)
        {
            me.releaseStyle(id, instance);
        }
    };

    /**
     * @private
     */
    function init()
    {
        me.head = document.getElementsByTagName('head').item(0);
        me.isIE = document.createStyleSheet ? true : false;
        if (window.Prj)
        {
            me.uriSuffix = '?' + window.Prj.version;
        }
        if (me.isIE)
        {
            me.fakeCss = '/skin/fake.css';
            me.styleContainersCount = 4;
            me.styleContainers = [];
            me.styleTags = [];
            for (var i = 0; i < me.styleContainersCount; i++)
            {
                me.styleContainers[i] = createStyleContainer('styleContainer.' + i, i);
            }
        }
    };

    /**
     * @private
     */
    function createStyleContainer(title, i)
    {
        var newStyle = pf.$$$('STYLE');
        newStyle.setAttribute('type', 'text/css');
        newStyle.title = title;
        me.styleTags[i] = newStyle;
        me.head.appendChild(newStyle);
        var stylesCount = document.styleSheets.length;
        for (var i = 0; i < stylesCount; i++)
        {
            if (document.styleSheets[i]['title'] == title)
            { return (document.styleSheets[i]); }
        }
        return (false);
    };

    /**
     * @private
     */
    function registerEntity(id, instance, type, loaderOptions)
    {
        if (!me.registry[id])
        {
            me.registry[id] = [];
            me.registry[id][0] = {};
            me.registry[id][0]['type'] = type;
            switch (type)
            {
                case 'link':
                {
                    me.registry[id][0]['object'] = createStyle(loaderOptions['uri'], loaderOptions['onReadyStateChange']);
                }
;
break;
                case 'inline':
                {
                    me.registry[id][0]['object'] = createInlineStyle(loaderOptions['style'], loaderOptions['id']);
                }
;
break;
            }
        }
        if (pf.arr.indexOf(me.registry[id], instance) < 1)
        {
            me.registry[id][me.registry[id].length] = instance;
        }
        afterLoad();
    };

    /**
     * @private
     */
    function afterLoad()
    {
        if (me.isIE)
        {
            setTimeout(function()
            {
                if (pf.elem.hasClass(document.body, 'cssRenderFix'))
                {
                    pf.elem.delClass(document.body, 'cssRenderFix');
                }
                else
                {
                    pf.elem.addClass(document.body, 'cssRenderFix');
                }
            }, 200);
        }
    };

    /**
     * @private
     */
    function createInlineStyle(style, id)
    {
        var stylesheet;
        if (me.isIE)
        {
            var index;
            for (var i = 0; i < me.styleContainersCount; i++)
            {
                if (me.styleContainers[i].imports.length < 31)
                {
                    index = me.styleContainers[i].addImport(me.fakeCss + '?' + id);
                    stylesheet = me.styleContainers[i].imports[index];
                    pf.evt.add(me.styleTags[i], 'readystatechange', fillReadyContainer);

                    function fillReadyContainer(evt)
                    {
                        if (me.styleTags[i].readyState == 'complete')
                        {
                            stylesheet.cssText = style;
                            pf.evt.remove(me.styleTags[i], 'readystatechange', fillReadyContainer);
                        }
                    }
                    break;
                }
            }
        }
        else
        {
            stylesheet = pf.$$$('STYLE');
            stylesheet.setAttribute('type', 'text/css');
            stylesheet.setAttribute('media', 'screen');
            stylesheet.setAttribute('title', id);
            stylesheet.appendChild(document.createTextNode(style));
            me.head.appendChild(stylesheet);
            enableStyleSheet(id);
        }
        return (stylesheet);
    };

    /**
     * @private
     */
    function createStyle(uri, onReadyStateChange)
    {
        var stylesheet;
        if (me.isIE)
        {
            var index;
            for (var i = 0; i < me.styleContainersCount; i++)
            {
                if (me.styleContainers[i].imports.length < 31)
                {
                    index = me.styleContainers[i].addImport(uri + me.uriSuffix);
                    stylesheet = me.styleContainers[i].imports[index];
                    break;
                }
            }
        }
        else
        {
            stylesheet = pf.$$$('LINK');
            stylesheet.setAttribute('rel', 'stylesheet');
            stylesheet.setAttribute('type', 'text/css');
            stylesheet.setAttribute('href', uri + me.uriSuffix);
            if (onReadyStateChange != null)
            {
                pf.evt.add(stylesheet, 'readystatechange', onReadyStateChange);
            }
            document.getElementsByTagName('head').item(0).appendChild(stylesheet);
        }
        return (stylesheet);
    };

    /**
     * @private
     */
    function enableStyleSheet(id)
    {
        var stylesheet = getStyleSheetById(id);
        if (stylesheet)
        {
            stylesheet.disabled = false;
        }
    };

    /**
     * @private
     */
    function getStyleSheetById(id)
    {
        var stylesheetsCount = document.styleSheets.length - 1;
        for (var i = stylesheetsCount; i >= 0; i--)
        {
            if (document.styleSheets[i]['title'] == id)
            { return (document.styleSheets[i]); }
        }
        return (null);
    };
    
    PuskFramework._initListeners.push(init);
};
