window.pfClientWidgetCore = function (main) {
    this.main = main;
    this.widgetAlbums   = new pfClientWidgetAlbums(this);
    this.widgetPhotos   = new pfClientWidgetPhotos(this);
    this.widgetIcons    = new pfClientWidgetIcons(this);
    this.widgetEtc      = new pfClientWidgetEtc(this);
    this.widgetUpload   = new pfClientWidgetUpload(this);

    // Определение текущего браузера
    this.userAgent       = navigator.userAgent.toLowerCase();
    this.is_opera        = (this.userAgent.indexOf('opera') != -1);
    this.is_saf          = ((this.userAgent.indexOf('applewebkit') != -1) || (navigator.vendor == 'Apple Computer, Inc.'));
    this.is_webtv        = (this.userAgent.indexOf('webtv') != -1);
    this.is_ie           = ((this.userAgent.indexOf('msie') != -1) && (!this.is_opera) && (!this.is_saf) && (!this.is_webtv));
    this.is_ie4          = ((this.is_ie) && (this.userAgent.indexOf('msie 4.') != -1));
    this.is_moz          = ((navigator.product == 'Gecko') && (!this.is_saf));
    this.is_kon          = (this.userAgent.indexOf('konqueror') != -1);
    this.is_ns           = ((this.userAgent.indexOf('compatible') == -1) && (this.userAgent.indexOf('mozilla') != -1) && (!this.is_opera) && (!this.is_webtv) && (!this.is_saf));
    this.is_ns4          = ((this.is_ns) && (parseInt(navigator.appVersion) == 4));
    this.is_mac          = (this.userAgent.indexOf('mac') != -1);


    /* общие методы */

    // получить элемент по id
    this.dom = function (id) {
        if (document.all) {
            return document.all[id];
        }
        else {
            return document.getElementById(id);
        }
    }
    
    // добавить текстовую ноду в контейнер
    this.write = function (cont, str) {
        cont.appendChild(document.createTextNode(str));
        return cont;
    }
    
    // создать ноду
    this.create = function (name, cont, className) {
        var elem = document.createElement(name);

        if (className != undefined && className != null) {
            elem.className = className;
        }

        if (cont != undefined && cont != null && typeof(cont) == "object") {
            cont.appendChild(elem);
        }

        return elem;
    }
    
    // создать простую ссылку
    this.createA = function (href, text, className, cont) {
        var a = this.create('a', cont, className);
        a.href = href;
        this.write(a, text);
        return a;
    }

    // вывести хэш
    this.debugHash = function (name, hash) {

        document.write("<br/><b>"+name+"</b> props:<pre>");

        var key;

        for (key in hash) {
            document.write("\n" + key + " => " + hash[key]);
        }

        document.write("</pre>");
    }

    // нарисовать резионовую таблицу
    this.drawRubberTable = function (cont, table, width) {
        var items = table.items;

        if (items.length == 0) {
            throw "empty items";
        }

        if (width == undefined || width == null || !width) {
            width = cont.offsetWidth;
        }

        var epp     = table.epp;
        var total   = items.length;

        var cols    = table.forceCols != undefined && table.forceCols != null
            ? table.forceCols 
            : Math.floor(width / table.itemWidth);
        cols = cols == 0 ? 1 : cols;
        var rows    = Math.ceil(epp / cols);
        epp = cols * rows;

        var pages   = Math.ceil(total / epp);
        var page    = table.page > pages || table.page < 1 ? 1 : table.page;

        /*
        document.write("<pre>"
            +"\ncont.clientWidth: " + cont.clientWidth
            +"\ncont.offsetWidth: " + cont.offsetWidth
            +"\ncont.width: " + cont.width
            +"\npage: "+page
            +"\ntotal: "+total
            +"\npages: "+pages
            +"\nper page: "+epp
            +"\ncols: "+cols
            +"\nrows: "+rows
            +"</pre>"
        );
        */

        //this.debugHash('cont', cont);
        //this.debugHash('cont.style', cont.style);

        table.epp   = epp;
        table.pages = pages;
        table.page  = page;


        this.drawTable(cont, table, items, cols, rows, page);
    }

    // нарисовать навигацию
    this.drawNav = function (cont, table) {

        var mult    = table.page * table.epp;
        var length  = table.items.length;
        var page    = table.page;
        var pages   = table.pages;

        this.write(cont, 'Показано '
            +(mult - table.epp + 1)
            +'-'
            +(mult > length ? length : mult)
            +' из '
            +length
            +'. '
        );

        this.drawNavLink(cont, page == 1 ? null : table.pageHref(1), '««', 'первая страница');

        this.write(cont, ' ');

        this.drawNavLink(cont, page == 1 ? null : table.pageHref(page - 1), '« пред', 'предыдущая страница');

        this.write(cont, ' | ');

        this.drawNavLink(cont, page == pages ? null : table.pageHref(page + 1), 'след »', 'следующая страница');

        this.write(cont, ' ');

        this.drawNavLink(cont, page == pages ? null : table.pageHref(pages), '»»', 'последняя страница');
    }

    this.drawNavLink = function (cont, href, str, title) {
        if (href == undefined || href == null) {
            this.write(cont, str);
        }
        else {
            var nav     = this.create('a', cont, 'bluelink');
            nav.href    = href;
            nav.title   = title;
            this.write(nav, str);
        }
    }

    this.drawNavOld = function (cont, table) {
        var page    = table.page;
        var pages   = table.pages;

        this.write(cont, 'Старицы: ');

        for (var j = 1; j <= pages; j++) {

            if (j == page) {
                var nav     = this.create('b', cont, 'bluelink');
            }
            else {
                var nav     = this.create('a', cont, 'bluelink');
                nav.href    = table.pageHref(j);
            }

            this.write(nav, ''+j);
            this.write(cont, ' ');
        }
    }

    // нарисовать таблицу
    this.drawTable = function (cont, table, elems, cols, rows, page) {
        var tbl     = this.create('table', null, 'list');
        var tbody   = this.create('tbody', tbl);

        var epp     = cols * rows;
        var total   = elems.length;

        var pst     = ''+Math.floor(100 / cols)+'%';

        for (var j = 0; j < rows; j ++) {

            var tr = this.create('tr', tbody, 'list');

            for (var k =0; k < cols; k++) {
                var td = this.create('td', tr, 'list');
                td.style.width = pst;

                var idx = (page - 1) * epp + k + j  * cols;

                if (idx >= total ) {
                    continue;
                }

                //elems[j].photosCount = idx;
                table.drawItem(td, elems[idx], idx);
            }
        }

        cont.appendChild(tbl);
    }

    this.splitLongWordsLazy = function (str) {
        return this.splitLongWords(str, 30);
    }

    this.splitLongWords = function (str, maxlen, limit) {
        if (maxlen == undefined || !maxlen) {
            maxlen = 20;
        }

        var reg = new RegExp('\\S{'+maxlen+',}', 'gi');

        var out = str.replace(reg, function (m) {
            var j;
            var ret = '';

            for (j = 0; j < m.length; j += maxlen - 1) {
                ret += ' ' + m.substring(j, j + maxlen - 1);
            }

            return ret;
        });

        return limit == undefined || limit == null ? out : this.cutWords(out, limit);
    }

    this.cutWords = function (str, limit) {
        return str.length > limit ? str.substring(0, limit)+' ...' : str;
    }

    this.clear = function (cont) {
        /*
        var children    = cont.childNodes;
        var j           = 0;
        var jlim        = children.length;

        for (j = 0; j < jlim; j++) {
            var child = children.item(j);
            cont.removeChild(child);
        }
        */
        cont.innerHTML = '';
    }

    // сделать кошерный input в зависимости от типа браузера
    this.createInput = function (tag, type, name, value, checked, cont, className) {
        var input;

        if (tag == undefined || tag == null) {
            tag = 'input';
        }

        if (this.is_ie) {
            if (checked)
                checked_param = ' checked="checked"';
            else
                checked_param = '';

            if (type != undefined && type != null)
                var type_param = ' type="'+type+'"';
            else
                var type_param = '';

            if (name != undefined && name != null)
                var name_param = ' name="'+name+'"';
            else
                var name_param = '';

            input = this.create('<'+tag+type_param+name_param+checked_param+'>', cont, className);
        }
        else {
            input = this.create(tag, cont, className);

            if (type != undefined && type != null)
                input.type = type;

            if (checked)
                input.checked = true;

            if (name != undefined && name != null)
                input.name = name;
        }

        if (value != null) {
            input.value = value;
        }

        return input;
    }
}

