
var browser = {
    opener: {},
    support: {},
    files: [],
    clipboard: [],
    labels: [],
    shows: [],
    orders: []
};

browser.initClipboard = function() {
    if (!this.clipboard || !this.clipboard.length) return;
    var size = 0;
    $.each(this.clipboard, function(i, val) {
        size += parseInt(val.size);
    });
    size = this.humanSize(size);
    $('#clipboard').html('<div title="' + this.label("Clipboard") + ' (' + this.clipboard.length + ' ' + this.label("files") + ', ' + size + ')" onclick="browser.openClipboard()"></div>');
    var resize = function() {
        $('#clipboard').css('left', $(window).width() - $('#clipboard').outerWidth() + 'px');
        $('#clipboard').css('top', $(window).height() - $('#clipboard').outerHeight() + 'px');
    };
    resize();
    $('#clipboard').css('display', 'block');
    $(window).unbind();
    $(window).resize(function() {
        browser.resize();
        resize();
    });
};

browser.openClipboard = function() {
    if (!this.clipboard || !this.clipboard.length) return;
    if ($('.menu a[href="kcact:cpcbd"]').html()) {
        $('#clipboard').removeClass('selected');
        this.hideDialog();
        return;
    }
    var html = '<div class="menu"><div class="list">';
    $.each(this.clipboard, function(i, val) {
        icon = _.getFileExtension(val.name);
        if (val.thumb)
            icon = ".image";
        else if (!val.smallIcon || !icon.length)
            icon = ".";
        var icon = 'themes/' + browser.theme + '/img/files/small/' + icon + '.png';
        html += '<a style="background-image:url(' + _.escapeDirs(icon) + ')" title="' + browser.label("Click to remove from the Clipboard") + '" onclick="browser.removeFromClipboard(' + i + ')">' + _.basename(val.name) + '</a>';
    });
    html += '</div><div class="delimiter"></div>';
    if (this.support.zip) html+=
        '<a href="kcact:download">' + this.label("Download files") + '</a>' +
        '<div class="delimiter"></div>';
    html +=
        '<a href="kcact:cpcbd"' + (!browser.dirWritable ? ' class="denied"' : '') + '>' + this.label("Copy files here") + '</a>' +
        '<a href="kcact:mvcbd"' + (!browser.dirWritable ? ' class="denied"' : '') + '>' + this.label("Move files here") + '</a>' +
        '<a href="kcact:rmcbd">' + this.label("Delete files") + '</a>' +
        '<div class="delimiter"></div>' +
        '<a href="kcact:clrcbd">' + this.label("Clear the Clipboard") + '</a>' +
    '</div>';

    setTimeout(function() {
        $('#clipboard').addClass('selected');
        $('#dialog').html(html);
        $('.menu a[href="kcact:download"]').click(function() {
            browser.hideDialog();
            browser.downloadClipboard();
            return false;
        });
        $('.menu a[href="kcact:cpcbd"]').click(function() {
            if (!browser.dirWritable) return false;
            browser.hideDialog();
            browser.copyClipboard(browser.dir);
            return false;
        });
        $('.menu a[href="kcact:mvcbd"]').click(function() {
            if (!browser.dirWritable) return false;
            browser.hideDialog();
            browser.moveClipboard(browser.dir);
            return false;
        });
        $('.menu a[href="kcact:rmcbd"]').click(function() {
            browser.hideDialog();
            if (confirm(browser.label("Are you sure you want to delete all files in the Clipboard?")))
                browser.deleteClipboard();
            return false;
        });
        $('.menu a[href="kcact:clrcbd"]').click(function() {
            browser.hideDialog();
            browser.clearClipboard();
            return false;
        });

        var left = $(window).width() - $('#dialog').outerWidth();
        var top = $(window).height() - $('#dialog').outerHeight() - $('#clipboard').outerHeight();
        var lheight = top + _.outerTopSpace('#dialog');
        $('.menu .list').css('max-height', lheight + 'px');
        var top = $(window).height() - $('#dialog').outerHeight() - $('#clipboard').outerHeight();
        $('#dialog').css('left', (left - 4) + 'px');
        $('#dialog').css('top', top + 'px');
        $('#dialog').fadeIn();
    }, 1);
};

browser.removeFromClipboard = function(i) {
    if (!this.clipboard || !this.clipboard[i]) return false;
    if (this.clipboard.length == 1) {
        this.clearClipboard();
        this.hideDialog();
        return;
    }

    if (i < this.clipboard.length - 1) {
        var last = this.clipboard.slice(i + 1);
        this.clipboard = this.clipboard.slice(0, i);
        this.clipboard = this.clipboard.concat(last);
    } else
        this.clipboard.pop();

    this.initClipboard();
    this.hideDialog();
    this.openClipboard();
    return true;
};

browser.copyClipboard = function(dir) {
    if (!this.clipboard || !this.clipboard.length) return;
    var files = [];
    var failed = 0;
    for (i = 0; i < this.clipboard.length; i++)
        if (this.clipboard[i].readable)
            files[i] = this.clipboard[i].dir + "/" + this.clipboard[i].name;
        else
            failed++;
    if (this.clipboard.length == failed) {
        alert(this.label("The files in the Clipboard are not readable."))
        return;
    }
    if (failed && !confirm(browser.label("{count} files in the Clipboard are not readable. Do you want to copy the rest?", {count:failed})))
        return;
    if (dir == browser.dir)
        this.fadeFiles();
    $.ajax({
        type: 'POST',
        url: browser.baseGetData('cp_cbd'),
        data: {dir:dir, files:files},
        async: false,
        success: function(xml) {
            browser.errors(xml);
            browser.clearClipboard();
            if (dir == browser.dir)
                browser.refresh();
        },
        error: function(request, error) {
            $('#files > div').css('opacity', '');
            $('#files > div').css('filter', '');
            alert(browser.label("Unknown error."));
        }
    });
};

browser.moveClipboard = function(dir) {
    if (!this.clipboard || !this.clipboard.length) return;
    var files = [];
    var failed = 0;
    for (i = 0; i < this.clipboard.length; i++)
        if (this.clipboard[i].readable && this.clipboard[i].writable)
            files[i] = this.clipboard[i].dir + "/" + this.clipboard[i].name;
        else
            failed++;
    if (this.clipboard.length == failed) {
        alert(this.label("The files in the Clipboard are not movable."))
        return;
    }
    if (failed && !confirm(browser.label("{count} files in the Clipboard are not movable. Do you want to move the rest?", {count: failed})))
        return;
    this.fadeFiles();
    $.ajax({
        type: 'POST',
        url: browser.baseGetData('mv_cbd'),
        data: {dir:dir, files:files},
        async: false,
        success: function(xml) {
            browser.errors(xml);
            browser.clearClipboard();
            browser.refresh();
        },
        error: function(request, error) {
            $('#files > div').css('opacity', '');
            $('#files > div').css('filter', '');
            alert(browser.label("Unknown error."));
        }
    });
};

browser.deleteClipboard = function() {
    if (!this.clipboard || !this.clipboard.length) return;
    var files = [];
    var failed = 0;
    for (i = 0; i < this.clipboard.length; i++)
        if (this.clipboard[i].readable && this.clipboard[i].writable)
            files[i] = this.clipboard[i].dir + "/" + this.clipboard[i].name;
        else
            failed++;
    if (this.clipboard.length == failed) {
        alert(this.label("The files in the Clipboard are not removable."))
        return;
    }
    if (failed && !confirm(browser.label("{count} files in the Clipboard are not removable. Do you want to delete the rest?", {count: failed})))
        return;
    this.fadeFiles();
    $.ajax({
        type: 'POST',
        url: browser.baseGetData('rm_cbd'),
        data: {files:files},
        async: false,
        success: function(xml) {
            browser.errors(xml);
            browser.clearClipboard();
            browser.refresh();
        },
        error: function(request, error) {
            $('#files > div').css({opacity:'', filter:''});
            alert(browser.label("Unknown error."));
        }
    });
};

browser.downloadClipboard = function() {
    if (!this.clipboard || !this.clipboard.length) return;
    var files = [];
    for (i = 0; i < this.clipboard.length; i++)
        if (this.clipboard[i].readable)
            files[i] = this.clipboard[i].dir + "/" + this.clipboard[i].name;
    if (files.length)
        this.post(this.baseGetData('downloadClipboard'), {files:files});
};

browser.clearClipboard = function() {
    $('#clipboard').html('');
    this.clipboard = [];
};

browser.initFiles = function() {
    $(document).unbind('keypress');
    $(document).keypress(function(e) {
        if ((e.which == 65) || (e.which == 97))
            browser.selectAll();
    });
    $('#files').unbind();
    $('#files').scroll(function() {
        browser.hideDialog();
    });
    $('.file').unbind();
    $('.file').click(function(e) {
        _.unselect();
        browser.selectFile($(this), e);
    });
    $('.file').rightClick(function(e) {
        _.unselect();
        browser.menuFile($(this), e);
    });
    $('.file').dblclick(function() {
        _.unselect();
        browser.returnFile($(this));
    });
    $('.file').mouseup(function() {
        _.unselect();
    });
    $('.file').mouseout(function() {
        _.unselect();
    });
    $.each(this.shows, function(i, val) {
        var display = (_.kuki.get('show' + val) == 'off')
            ? 'none' : 'block';
        $('#files .file div.' + val).css('display', display);
    });
    this.statusDir();
};

browser.loadFiles = function(files) {
    this.files = [];
    $.each(files, function(i, file) {
        browser.files[i] = {
            name: file.getElementsByTagName('name')[0].childNodes[0].nodeValue,
            size: file.getAttribute('size'),
            mtime: file.getAttribute('mtime'),
            date: file.getAttribute('date'),
            readable: file.getAttribute('readable') == 'yes',
            writable: file.getAttribute('writable') == 'yes',
            bigIcon: file.getAttribute('bigIcon') == 'yes',
            smallIcon: file.getAttribute('smallIcon') == 'yes',
            thumb: file.getAttribute('thumb') == 'yes',
            smallThumb: file.getAttribute('smallThumb') == 'yes'
        };
    });
};

browser.showFiles = function(callBack, selected) {
    this.fadeFiles();
    setTimeout(function() {
        var html = '';
        $.each(browser.files, function(i, file) {
            if (_.kuki.get('view') == 'list') {
                if (!i) html += '<table summary="list">';
                var icon = _.getFileExtension(file.name);
                if (file.thumb)
                    icon = ".image";
                else if (!icon.length || !file.smallIcon)
                    icon = ".";
                icon = 'themes/' + browser.theme + '/img/files/small/' + icon + '.png';
                html += '<tr class="file">' +
                    '<td class="name" style="background-image:url(' + icon + ')">' + file.name + '</td>' +
                    '<td class="time">' + file.date + '</td>' +
                    '<td class="size">' + browser.humanSize(file.size) + '</td>' +
                '</tr>';
                if (i == browser.files.length - 1) html += '</table>';
            } else {
                if (file.thumb)
                    var icon = browser.baseGetData('thumb') + '&file=' + encodeURIComponent(file.name);
                else if (file.smallThumb) {
                    var icon = browser.uploadURL + '/' + browser.dir + '/' + file.name;
                    icon = _.escapeDirs(icon);
                } else {
                    var icon = file.bigIcon ? _.getFileExtension(file.name) : ".";
                    if (!icon.length) icon = ".";
                    icon = 'themes/' + browser.theme + '/img/files/big/' + icon + '.png';
                }
                html += '<div class="file">' +
                    '<div class="thumb" style="background-image:url(\'' + icon + '\')" ></div>' +
                    '<div class="name">' + file.name + '</div>' +
                    '<div class="time">' + file.date + '</div>' +
                    '<div class="size">' + browser.humanSize(file.size) + '</div>' +
                '</div>';
            }
        });
        $('#files').html('<div>' + html + '<div>');
        $.each(browser.files, function(i, file) {
            var item = $('#files .file').get(i);
            $(item).data(file);
            if (file.name == selected)
            $(item).addClass('selected');
        });
        $('#files > div').css({opacity:'', filter:''});
        if (callBack) callBack();
        browser.initFiles();
    }, 200);
};

browser.selectFile = function(file, e) {
    if (e.ctrlKey) {
        if (file.hasClass('selected'))
            file.removeClass('selected');
        else
            file.addClass('selected');
        var files = $('.file.selected').get();
        var size = 0;
        if (!files.length)
            this.statusDir();
        else {
            $.each(files, function(i, cfile) {
                size += parseInt($(cfile).data('size'));
            });
            size = this.humanSize(size);
            if (files.length > 1)
                $('#fileinfo').html(files.length + ' ' + this.label("selected files") + ' (' + size + ')');
            else {
                var data = $(files[0]).data();
                $('#fileinfo').html(data.name + ' (' + this.humanSize(data.size) + ', ' + data.date + ')');
            }
        }
    } else {
        var data = file.data();
        $('.file').removeClass('selected');
        file.addClass('selected');
        $('#fileinfo').html(data.name + ' (' + this.humanSize(data.size) + ', ' + data.date + ')');
    }
};

browser.selectAll = function() {
    var files = $('.file').get();
    if (files.length) {
        var size = 0;
        $.each(files, function(i, file) {
            if (!$(file).hasClass('selected'))
                $(file).addClass('selected');
            size += parseInt($(file).data('size'));
        });
        size = this.humanSize(size);
        $('#fileinfo').html(files.length + ' ' + this.label("selected files") + ' (' + size + ')');
    }
};

browser.returnFile = function(file) {
    var fileURL = file.substr
        ? file : browser.uploadURL + '/' + browser.dir + '/' + file.data('name');
    fileURL = _.escapeDirs(fileURL);

    if (this.opener.CKEditor) {
        this.opener.CKEditor.object.tools.callFunction(this.opener.CKEditor.funcNum, fileURL, '');
        window.close();

    } else if (this.opener.FCKeditor) {
        window.opener.SetUrl(fileURL) ;
        window.close() ;

    } else if (this.opener.TinyMCE) {
        var win = tinyMCEPopup.getWindowArg('window');
        win.document.getElementById(tinyMCEPopup.getWindowArg('input')).value = fileURL;
        if (win.getImageData) win.getImageData();
        if (typeof(win.ImageDialog) != "undefined") {
            if (win.ImageDialog.getImageData)
                win.ImageDialog.getImageData();
            if (win.ImageDialog.showPreviewImage)
                win.ImageDialog.showPreviewImage(fileURL);
        }
        tinyMCEPopup.close();

    } else if (this.opener.callBack) {
        if (window.opener.KCFinder) {
            this.opener.callBack(fileURL);
            window.close();
        }

        if (window.parent.KCFinder) {
            var button = $('#toolbar a[href="kcact:maximize"]');
            if (button.hasClass('selected'))
                this.maximize(button);
            this.opener.callBack(fileURL);
        }

    } else if (this.opener.callBackMultiple) {
        if (window.opener.KCFinder) {
            this.opener.callBackMultiple([fileURL]);
            window.close();
        }

        if (window.parent.KCFinder) {
            var button = $('#toolbar a[href="kcact:maximize"]');
            if (button.hasClass('selected'))
                this.maximize(button);
            this.opener.callBackMultiple([fileURL]);
        }

    }
};

browser.returnFiles = function(files) {
    if (this.opener.callBackMultiple && files.length) {
        var rfiles = [];
        $.each(files, function(i, file) {
            rfiles[i] = browser.uploadURL + '/' + browser.dir + '/' + $(file).data('name');
            rfiles[i] = _.escapeDirs(rfiles[i]);
        });
        this.opener.callBackMultiple(rfiles);
        if (window.opener) window.close()
    }
};

browser.returnThumbnails = function(files) {
    if (this.opener.callBackMultiple) {
        var rfiles = [];
        var j = 0;
        $.each(files, function(i, file) {
            if ($(file).data('thumb')) {
                rfiles[j] = browser.thumbsURL + '/' + browser.dir + '/' + $(file).data('name');
                rfiles[j] = _.escapeDirs(rfiles[j++]);
            }
        });
        this.opener.callBackMultiple(rfiles);
        if (window.opener) window.close()
    }
};

browser.menuFile = function(file, e) {
    var data = file.data();
    var path = this.dir + '/' + data.name;
    var files = $('.file.selected').get();
    var html = '<div class="menu">';

    if (file.hasClass('selected') && files.length && (files.length > 1)) {
        var thumb = false;
        var notWritable = 0;
        var cdata;
        $.each(files, function(i, cfile) {
            cdata = $(cfile).data();
            if (cdata.thumb) thumb = true;
            if (!data.writable) notWritable++;
        });
        if (this.opener.callBackMultiple) {
            html += '<a href="kcact:pick">' + this.label("Select") + '</a>';
            if (thumb) html +=
                '<a href="kcact:pick_thumb">' + this.label("Select Thumbnails") + '</a>';
            html += '<div class="delimiter"></div>';
        }
        if (this.support.zip) html+=
            '<a href="kcact:download">' + this.label("Download") + '</a>' +
            '<div class="delimiter"></div>';
        html +=
            '<a href="kcact:clpbrdadd">' + this.label("Add to Clipboard") + '</a>' +
            '<div class="delimiter"></div>' +
            '<a href="kcact:rm"' + ((notWritable == files.length) ? ' class="denied"' : '') + '>' + this.label("Delete") + '</a>' +
        '</div>';

        $('#dialog').html(html);
        this.showMenu(e);

        $('.menu a[href="kcact:pick"]').click(function() {
            browser.returnFiles(files);
            browser.hideDialog();
            return false;
        });

        $('.menu a[href="kcact:pick_thumb"]').click(function() {
            browser.returnThumbnails(files);
            browser.hideDialog();
            return false;
        });

        $('.menu a[href="kcact:download"]').click(function() {
            browser.hideDialog();
            var pfiles = [];
            $.each(files, function(i, cfile) {
                pfiles[i] = $(cfile).data('name');
            });
            browser.post(browser.baseGetData('downloadSelected'), {dir:browser.dir, files:pfiles});
            return false;
        });

        $('.menu a[href="kcact:clpbrdadd"]').click(function() {
            browser.hideDialog();
            var msg = '';
            $.each(files, function(i, cfile) {
                var cdata = $(cfile).data();
                var failed = false;
                for (i = 0; i < browser.clipboard.length; i++)
                    if ((browser.clipboard[i].name == cdata.name) &&
                        (browser.clipboard[i].dir == browser.dir)
                    ) {
                        failed = true
                        msg += cdata.name + ": " + browser.label("This file is already added to the Clipboard.") + "\n";
                        break;
                    }

                if (!failed) {
                    cdata.dir = browser.dir;
                    browser.clipboard[browser.clipboard.length] = cdata;
                }
            });
            browser.initClipboard();
            if (msg.length) alert(msg.substr(0, msg.length - 1));
            return false;
        });

        $('.menu a[href="kcact:rm"]').click(function() {
            if ($(this).hasClass('denied')) return false;
            browser.hideDialog();
            var failed = 0;
            var dfiles = [];
            $.each(files, function(i, cfile) {
                var cdata = $(cfile).data();
                if (!cdata.writable)
                    failed++;
                else
                    dfiles[dfiles.length] = browser.dir + "/" + cdata.name;
            });
            if (failed == files.length) {
                alert(browser.label("The selected files are not removable."))
                return false;
            }
            if (failed) {
                if (!confirm(browser.label("{count} selected files are not removable. Do you want to delete the rest?", {count:failed})))
                    return false;
            } else if (!confirm(browser.label("Are you sure you want to delete all selected files?")))
                return false;

            browser.fadeFiles();
            $.ajax({
                type: 'POST',
                url: browser.baseGetData('rm_cbd'),
                data: {files:dfiles},
                async: false,
                success: function(xml) {
                    browser.errors(xml);
                    browser.refresh();
                },
                error: function(request, error) {
                    $('#files > div').css('opacity', '');
                    $('#files > div').css('filter', '');
                    alert(browser.label("Unknown error."));
                }
            });
            return false;
        });

    } else {
        $('.file').removeClass('selected');
        file.addClass('selected');
        $('#fileinfo').html(data.name + ' (' + this.humanSize(data.size) + ', ' + data.date + ')');
        if (this.opener.callBack || this.opener.callBackMultiple) {
            html += '<a href="kcact:pick">' + this.label("Select") + '</a>';
            if (data.thumb) html +=
                '<a href="kcact:pick_thumb">' + this.label("Select Thumbnail") + '</a>';
            html += '<div class="delimiter"></div>';
        }

        if (data.thumb)
            html +='<a href="kcact:view">' + this.label("View") + '</a>';

        html +=
            '<a href="kcact:download">' + this.label("Download") + '</a>' +
            '<div class="delimiter"></div>' +
            '<a href="kcact:clpbrdadd">' + this.label("Add to Clipboard") + '</a>' +
            '<div class="delimiter"></div>' +
            '<a href="kcact:mv"' + (!data.writable ? ' class="denied"' : '') + '>' + this.label("Rename...") + '</a>' +
            '<a href="kcact:rm"' + (!data.writable ? ' class="denied"' : '') + '>' + this.label("Delete") + '</a>' +
        '</div>';

        $('#dialog').html(html);
        this.showMenu(e);

        $('.menu a[href="kcact:pick"]').click(function() {
            browser.returnFile(file);
            browser.hideDialog();
            return false;
        });

        $('.menu a[href="kcact:pick_thumb"]').click(function() {
            var path = browser.thumbsURL + "/" + browser.dir + '/' + data.name;
            browser.returnFile(path);
            browser.hideDialog();
            return false;
        });

        $('.menu a[href="kcact:view"]').click(function() {
            browser.hideDialog();
            $('#loading').html(browser.label("Loading image..."));
            $('#loading').css('display', 'inline');
            var img = new Image();
            var url = _.escapeDirs(browser.uploadURL + '/' + path);
            img.src = url;
            img.onload = function() {
                $('#loading').css('display', 'none');
                $('#dialog').html('<img />');
                $('#dialog img').attr('src', url);
                var o_w = $('#dialog').outerWidth();
                var o_h = $('#dialog').outerHeight();
                var f_w = $(window).width() - 30;
                var f_h = $(window).height() - 30;
                if ((o_w > f_w) || (o_h > f_h)) {
                    if ((f_w / f_h) > (o_w / o_h))
                        f_w = parseInt((o_w * f_h) / o_h);
                    else if ((f_w / f_h) < (o_w / o_h))
                        f_h = parseInt((o_h * f_w) / o_w);
                    $('#dialog img').attr('width', f_w);
                    $('#dialog img').attr('height', f_h);
                }
                $('#dialog').click(function() {
                    browser.hideDialog();
                });
                browser.showDialog();
            }
            return false;
        });

        $('.menu a[href="kcact:download"]').click(function() {
            var html = '<form id="downloadForm" method="post" action="' + browser.baseGetData('download') + '">' +
                '<input type="hidden" name="dir" />' +
                '<input type="hidden" name="file" />' +
            '</form>';
            $('#dialog').html(html);
            $('#downloadForm input').get(0).value = browser.dir;
            $('#downloadForm input').get(1).value = data.name;
            $('#downloadForm').submit();
            return false;
        });

        $('.menu a[href="kcact:clpbrdadd"]').click(function() {
            for (i = 0; i < browser.clipboard.length; i++)
                if ((browser.clipboard[i].name == data.name) &&
                    (browser.clipboard[i].dir == browser.dir)
                ) {
                    browser.hideDialog();
                    alert(browser.label("This file is already added to the Clipboard."));
                    return false;
                }
            var cdata = data;
            cdata.dir = browser.dir;
            browser.clipboard[browser.clipboard.length] = cdata;
            browser.initClipboard();
            browser.hideDialog();
            return false;
        });

        $('.menu a[href="kcact:mv"]').click(function(e) {
            if (!data.writable) return false;
            browser.fileNameDialog(
                e, {dir: browser.dir, file: data.name},
                'newName', data.name, browser.baseGetData('rename'), {
                    title: "New file name:",
                    errEmpty: "Please enter new file name.",
                    errSlash: "Unallowable characters in file name.",
                    errDot: "File name shouldn't begins with '.'"
                },
                function() {
                    browser.refresh();
                }
            );
            return false;
        });

        $('.menu a[href="kcact:rm"]').click(function() {
            if (!data.writable) return false;
            browser.hideDialog();
            if (confirm(browser.label(
                "Are you sure you want to delete this file?"
            )))
                $.ajax({
                    type: 'POST',
                    url: browser.baseGetData('delete'),
                    data: {dir:browser.dir, file:data.name},
                    async: false,
                    success: function(xml) {
                        browser.clearClipboard();
                        if (browser.errors(xml)) return;
                        browser.refresh();
                    },
                    error: function(request, error) {
                        alert(browser.label("Unknown error."));
                    }
                });
            return false;
        });
    }
};

browser.initFolders = function() {
    $('#folders').scroll(function() {
        browser.hideDialog();
    });
    $('div.folder > a').unbind();
    $('div.folder > a').bind('click', function() {
        browser.hideDialog();
        return false;
    });
    $('div.folder > a > span.brace').unbind();
    $('div.folder > a > span.brace').click(function() {
        if ($(this).hasClass('opened') || $(this).hasClass('closed'))
            browser.expandDir($(this).parent());
    });
    $('div.folder > a > span.folder').unbind();
    $('div.folder > a > span.folder').click(function() {
        browser.changeDir($(this).parent());
    });
    $('div.folder > a > span.folder').rightClick(function(e) {
        browser.menuDir($(this).parent(), e);
    });

    if ($.browser.msie && $.browser.version &&
        (parseInt($.browser.version.substr(0, 1)) < 8)
    ) {
        var fls = $('div.folder').get();
        var body = $('body').get(0);
        var div;
        $.each(fls, function(i, folder) {
            div = document.createElement('div');
            div.style.display = 'inline';
            div.style.margin = div.style.border = div.style.padding = '0';
            div.innerHTML='<table style="border-collapse:collapse;border:0;margin:0;width:0"><tr><td nowrap="nowrap" style="white-space:nowrap;padding:0;border:0">' + $(folder).html() + "</td></tr></table>";
            body.appendChild(div);
            $(folder).css('width', $(div).innerWidth() + 'px');
            body.removeChild(div);
        });
    }
};

browser.setTreeData = function(xml, path) {
    if (!path)
        path = "";
    else if (path.length && (path.substr(path.length - 1, 1) != '/'))
        path += '/';
    var data = {
        name: xml.getElementsByTagName('name')[0].childNodes[0].nodeValue,
        readable: xml.getAttribute('readable') == 'yes',
        writable: xml.getAttribute('writable') == 'yes',
        removable: xml.getAttribute('removable') == 'yes',
        hasDirs: xml.getAttribute('hasDirs') == 'yes',
        current: xml.getAttribute('current') ? true : false
    };
    path += data.name;
    var selector = '#folders a[href="kcdir:/' + _.htmlValue(path) + '"]';
    $(selector).data({
        name: data.name,
        path: path,
        readable: data.readable,
        writable: data.writable,
        removable: data.removable,
        hasDirs: data.hasDirs
    });
    $(selector + ' span.folder').addClass(data.current ? 'current' : 'regular');
    if (xml.getElementsByTagName('dirs').length) {
        $(selector + ' span.brace').addClass('opened');
        var dirs = xml.getElementsByTagName('dirs')[0];
        $.each(dirs.childNodes, function(i, cdir) {
            browser.setTreeData(cdir, path + '/');
        });
    } else if (data.hasDirs)
        $(selector + ' span.brace').addClass('closed');
};

browser.buildTree = function(xml, path) {
    if (!path) path = "";
    var name = xml.getElementsByTagName('name')[0].childNodes[0].nodeValue;
    var hasDirs = xml.getAttribute('hasDirs') == 'yes';
    path += name;
    var html = '<div class="folder"><a href="kcdir:/' + _.htmlValue(path) + '"><span class="brace">&nbsp;</span><span class="folder">' + name + '</span></a>';
    if (xml.getElementsByTagName('dirs').length) {
        var dirs = xml.getElementsByTagName('dirs')[0];
        html += '<div class="folders">';
        $.each(dirs.childNodes, function(i, cdir) {
            html += browser.buildTree(cdir, path + '/');
        });
        html += '</div>';
    }
    html += '</div>';
    return html;
};

browser.expandDir = function(dir, callBack) {
    var path = dir.data('path');
    if (dir.children('.brace').hasClass('opened')) {
        dir.parent().children('.folders').hide(500, function() {
            if (path == browser.dir.substr(0, path.length))
                browser.changeDir(dir);
        });
        dir.children('.brace').removeClass('opened');
        dir.children('.brace').addClass('closed');
        if (callBack) callBack();
    } else {
        if (dir.parent().children('.folders').get(0)) {
            dir.parent().children('.folders').show(500);
            dir.children('.brace').removeClass('closed');
            dir.children('.brace').addClass('opened');
            if (callBack) callBack();
        } else if (!$('#loadingDirs').get(0)) {
            dir.parent().append('<div id="loadingDirs">' + this.label("Loading folders...") + '</div>');
            $('#loadingDirs').css('display', 'none');
            $('#loadingDirs').show(200, function() {
                $.ajax({
                    type: 'POST',
                    url: browser.baseGetData('expand'),
                    data: {dir:path},
                    async: false,
                    success: function(xml) {
                        $('#loadingDirs').hide(200, function() {
                            $('#loadingDirs').detach();
                        });
                        if (browser.errors(xml)) return;
                        var dirs = xml.getElementsByTagName('dir');
                        var html = '';
                        var pth, name, hadDirs;
                        $.each(dirs, function(i, cdir) {
                            name = cdir.getElementsByTagName('name')[0].childNodes[0].nodeValue;
                            hasDirs = cdir.getAttribute('hasDirs') == 'yes';
                            pth = path + '/' + name;
                            html += '<div class="folder"><a href="kcdir:/' + _.htmlValue(pth) + '"><span class="brace">&nbsp;</span><span class="folder">' + name + '</span></a></div>';
                        });
                        if (html.length) {
                            dir.parent().append('<div class="folders">' + html + '</div>');
                            var folders = $(dir.parent().children('.folders').first());
                            folders.css('display', 'none');
                            $(folders).show(500);
                            $.each(dirs, function(i, cdir) {
                                browser.setTreeData(cdir, path, true);
                            });
                        }
                        if (dirs.length) {
                            dir.children('.brace').removeClass('closed');
                            dir.children('.brace').addClass('opened');
                        } else {
                            dir.children('.brace').removeClass('opened');
                            dir.children('.brace').removeClass('closed');
                        }

                        browser.initFolders();
                        if (callBack) callBack(xml);
                    },
                    error: function(request, error) {
                        $('#loadingDirs').detach();
                        alert(browser.label("Unknown error."));
                    }
                });
            });
        }
    }
};

browser.changeDir = function(dir) {
    if (dir.children('span.folder').hasClass('regular')) {
        $('div.folder > a > span.folder').removeClass('current');
        $('div.folder > a > span.folder').removeClass('regular');
        $('div.folder > a > span.folder').addClass('regular');
        dir.children('span.folder').removeClass('regular');
        dir.children('span.folder').addClass('current');
        $('#files').html(browser.label("Loading files..."));
        $.ajax({
            type: 'POST',
            url: browser.baseGetData('chDir'),
            data: {dir:dir.data('path')},
            async: false,
            success: function(xml) {
                if (browser.errors(xml)) return;
                var files = xml.getElementsByTagName('file');
                browser.loadFiles(files);
                browser.orderFiles();
                browser.dir = dir.data('path');
                var dirWritable =
                    xml.getElementsByTagName('files')[0].getAttribute('dirWritable');
                browser.dirWritable = (dirWritable == 'yes');
                var title = "KCFinder: /" + browser.dir;
                document.title = title;
                if (browser.opener.TinyMCE)
                    tinyMCEPopup.editor.windowManager.setTitle(window, title);
                browser.statusDir();
            },
            error: function(request, error) {
                $('#files').html(browser.label("Unknown error."));
            }
        });
    }
};

browser.statusDir = function() {
    for (var i = 0, size = 0; i < this.files.length; i++)
        size += parseInt(this.files[i].size);
    size = this.humanSize(size);
    $('#fileinfo').html(this.files.length + ' ' + this.label("files") + ' (' + size + ')');
};

browser.menuDir = function(dir, e) {
    var data = dir.data();
    var html = '<div class="menu">';
    if (this.clipboard && this.clipboard.length) html +=
        '<a href="kcact:cpcbd"' + (!data.writable ? ' class="denied"' : '') + '>' + this.label("Copy {count} files", {count: this.clipboard.length}) + '</a>' +
        '<a href="kcact:mvcbd"' + (!data.writable ? ' class="denied"' : '') + '>' + this.label("Move {count} files", {count: this.clipboard.length}) + '</a>' +
        '<div class="delimiter"></div>';
    html +=
        '<a href="kcact:refresh">' + this.label("Refresh") + '</a>' +
        '<div class="delimiter"></div>';
    if (this.support.zip) html+=
        '<a href="kcact:download">' + this.label("Download") + '</a>' +
        '<div class="delimiter"></div>';
    html +=
        '<a href="kcact:mkdir"' + (!data.writable ? ' class="denied"' : '') + '>' + this.label("New Subfolder...") + '</a>' +
        '<a href="kcact:mvdir"' + (!data.removable ? ' class="denied"' : '') + '>' + this.label("Rename...") + '</a>' +
        '<a href="kcact:rmdir"' + (!data.removable ? ' class="denied"' : '') + '>' + this.label("Delete") + '</a>' +
    '</div>';
    $('#dialog').html(html);
    this.showMenu(e);
    $('div.folder > a > span.folder').removeClass('context');
    if (dir.children('span.folder').hasClass('regular'))
        dir.children('span.folder').addClass('context');

    if (this.clipboard && this.clipboard.length && data.writable) {

        $('.menu a[href="kcact:cpcbd"]').click(function() {
            browser.hideDialog();
            browser.copyClipboard(data.path);
            return false;
        });

        $('.menu a[href="kcact:mvcbd"]').click(function() {
            browser.hideDialog();
            browser.moveClipboard(data.path);
            return false;
        });
    }

    $('.menu a[href="kcact:refresh"]').click(function() {
        browser.hideDialog();
        browser.refreshDir(dir);
        return false;
    });

    $('.menu a[href="kcact:download"]').click(function() {
        browser.hideDialog();
        browser.post(browser.baseGetData('downloadDir'), {dir:data.path});
        return false;
    });

    $('.menu a[href="kcact:mkdir"]').click(function(e) {
        if (!data.writable) return false;
        browser.hideDialog();
        browser.fileNameDialog(
            e, {dir: data.path},
            'newDir', '', browser.baseGetData('newDir'), {
                title: "New folder name:",
                errEmpty: "Please enter new folder name.",
                errSlash: "Unallowable characters in folder name.",
                errDot: "Folder name shouldn't begins with '.'"
            }, function(xml) {
                browser.refreshDir(dir);
                if (!data.hasDirs) {
                    dir.data('hasDirs', true);
                    dir.children('span.brace').addClass('closed');
                }
            }
        );
        return false;
    });

    $('.menu a[href="kcact:mvdir"]').click(function(e) {
        if (!data.removable) return false;
        browser.hideDialog();
        browser.fileNameDialog(
            e, {dir: data.path},
            'newName', data.name, browser.baseGetData('renameDir'), {
                title: "New folder name:",
                errEmpty: "Please enter new folder name.",
                errSlash: "Unallowable characters in folder name.",
                errDot: "Folder name shouldn't begins with '.'"
            }, function(xml) {
                if (!xml.getElementsByTagName('name').length) {
                    alert(browser.label("Unknown error."));
                    return;
                }
                var name = xml.getElementsByTagName('name')[0].childNodes[0].nodeValue;
                dir.children('span.folder').html(name);
                dir.data('name', name);
                dir.data('path', _.dirname(data.path) + '/' + name);
                if (data.path == browser.dir)
                    browser.dir = dir.data('path');
            }
        );
        return false;
    });

    $('.menu a[href="kcact:rmdir"]').click(function() {
        if (!data.removable) return false;
        browser.hideDialog();
        if (confirm(browser.label(
            "Are you sure you want to delete this folder and all its content?"
        ))) {
            $.ajax({
                type: 'POST',
                url: browser.baseGetData('deleteDir'),
                data: {dir:data.path},
                async: false,
                success: function(xml) {
                    if (browser.errors(xml)) return;
                    dir.parent().hide(500, function() {
                        var folders = dir.parent().parent();
                        var pDir = folders.parent().children('a').first();
                        dir.parent().detach();
                        if (!folders.children('div.folder').get(0)) {
                            pDir.children('span.brace').first().removeClass('opened');
                            pDir.children('span.brace').first().removeClass('closed');
                            pDir.parent().children('.folders').detach();
                            pDir.data('hasDirs', false);
                        }
                        if (pDir.data('path') == browser.dir.substr(0, pDir.data('path').length))
                            browser.changeDir(pDir);
                    });
                },
                error: function(request, error) {
                    alert(browser.label("Unknown error."));
                }
            });
        }
        return false;
    });
};

browser.refreshDir = function(dir) {
    var path = dir.data('path');
    if (dir.children('.brace').hasClass('opened') || dir.children('.brace').hasClass('closed')) {
        dir.children('.brace').removeClass('opened');
        dir.children('.brace').addClass('closed');
    }
    dir.parent().children('.folders').first().detach();
    if (path == browser.dir.substr(0, path.length))
        browser.changeDir(dir);
    browser.expandDir(dir);
    return true;
};
browser.init = function() {
    if (!this.checkAgent()) return;

    $('body').click(function() {
        browser.hideDialog();
    });
    $('#shadow').click(function() {
        return false;
    });
    $('#dialog').unbind();
    $('#dialog').click(function() {
        return false;
    });
    this.initOpeners();
    this.initSettings();
    this.initContent();
    this.initToolbar();
    this.initResizer();
};

browser.checkAgent = function() {
    if (!$.browser.version ||
        ($.browser.msie && (parseInt($.browser.version) < 7) && !this.support.chromeFrame) ||
        ($.browser.opera && (parseInt($.browser.version) < 10)) ||
        ($.browser.mozilla && (parseFloat($.browser.version.replace(/^(\d+(\.\d+)?)([^\d].*)?$/, "$1")) < 1.8))
    ) {
        var html = '<div style="padding:10px">Your browser is not capable to display KCFinder. Please update your browser or install another one: <a href="http://www.mozilla.com/firefox/" target="_blank">Mozilla Firefox</a>, <a href="http://www.apple.com/safari" target="_blank">Apple Safari</a>, <a href="http://www.google.com/chrome" target="_blank">Google Chrome</a>, <a href="http://www.opera.com/browser" target="_blank">Opera</a>.';
        if ($.browser.msie)
            html += ' You may also install <a href="http://www.google.com/chromeframe" target="_blank">Google Chrome Frame ActiveX plugin</a> to get Internet Explorer 6 working.';
        html += '</div>';
        $('body').html(html);
        return false;
    }
    return true;
};

browser.initOpeners = function() {
    if (this.opener.TinyMCE && (typeof(tinyMCEPopup) == 'undefined'))
        this.opener.TinyMCE = null;

    if (this.opener.TinyMCE)
        this.opener.callBack = true;

    if ((!this.opener.name || (this.opener.name == 'fckeditor')) &&
        window.opener && window.opener.SetUrl
    ) {
        this.opener.FCKeditor = true;
        this.opener.callBack = true;
    }

    if (this.opener.CKEditor) {
        if (window.parent && window.parent.CKEDITOR)
            this.opener.CKEditor.object = window.parent.CKEDITOR;
        else if (window.opener && window.opener.CKEDITOR) {
            this.opener.CKEditor.object = window.opener.CKEDITOR;
            this.opener.callBack = true;
        } else
            this.opener.CKEditor = null;
    }

    if (!this.opener.CKFinder && !this.opener.FCKEditor && !this.TinyMCE) {
        if ((window.opener && window.opener.KCFinder && window.opener.KCFinder.callBack) ||
            (window.parent && window.parent.KCFinder && window.parent.KCFinder.callBack)
        )
            this.opener.callBack = window.opener
                ? window.opener.KCFinder.callBack
                : window.parent.KCFinder.callBack;

        if ((
                window.opener &&
                window.opener.KCFinder &&
                window.opener.KCFinder.callBackMultiple
            ) || (
                window.parent &&
                window.parent.KCFinder &&
                window.parent.KCFinder.callBackMultiple
            )
        )
            this.opener.callBackMultiple = window.opener
                ? window.opener.KCFinder.callBackMultiple
                : window.parent.KCFinder.callBackMultiple;
    }
};

browser.initContent = function() {
    $('div#folders').html(this.label("Loading folders..."));
    $('div#files').html(this.label("Loading files..."));
    $.ajax({
        type: 'GET',
        url: browser.baseGetData('init'),
        async: false,
        success: function(xml) {
            if (browser.errors(xml)) return;
            var dirWritable = xml.getElementsByTagName('files')[0].getAttribute('dirWritable');
            browser.dirWritable = (dirWritable == 'yes');
            var tree = xml.getElementsByTagName('tree')[0].getElementsByTagName('dir')[0];
            $('#folders').html(browser.buildTree(tree));
            browser.setTreeData(tree);
            browser.initFolders();
            var files = xml.getElementsByTagName('files')[0].getElementsByTagName('file');
            browser.loadFiles(files);
            browser.orderFiles();
        },
        error: function(request, error) {
            $('div#folders').html(browser.label("Unknown error."));
            $('div#files').html(browser.label("Unknown error."));
        }
    });
};

browser.initResizer = function() {
    var cursor = ($.browser.opera) ? 'move' : 'col-resize';
    $('#resizer').css('cursor', cursor);
    $('#resizer').drag('start', function() {
        $(this).css({opacity:'0.4', filter:'alpha(opacity:40)'});
        $('#all').css('cursor', cursor);
    });
    $('#resizer').drag(function(e) {
        var left = e.pageX - parseInt(_.nopx($(this).css('width')) / 2);
        left = (left >= 0) ? left : 0;
        left = (left + _.nopx($(this).css('width')) < $(window).width())
            ? left : $(window).width() - _.nopx($(this).css('width'));
		$(this).css('left', left);
	});
	var end = function() {
        $(this).css({opacity:'0', filter:'alpha(opacity:0)'});
        $('#all').css('cursor', '');
        var left = _.nopx($(this).css('left')) + _.nopx($(this).css('width'));
        var right = $(window).width() - left;
        $('#left').css('width', left + 'px');
        $('#right').css('width', right + 'px');
        _('files').style.width = $('#right').innerWidth() - _.outerHSpace('#files') + 'px';
        _('resizer').style.left = $('#left').outerWidth() - _.outerRightSpace('#folders', 'm') + 'px';
        _('resizer').style.width = _.outerRightSpace('#folders', 'm') + _.outerLeftSpace('#files', 'm') + 'px';
        browser.fixFilesHeight();
    };
    $('#resizer').drag('end', end);
    $('#resizer').mouseup(end);
};

browser.resize = function() {
    _('left').style.width = '25%';
    _('right').style.width = '75%';
    _('toolbar').style.height = $('#toolbar a').outerHeight() + "px";
    _('shadow').style.width = $(window).width() + 'px';
    _('shadow').style.height = _('resizer').style.height = $(window).height() + 'px';
    _('left').style.height = _('right').style.height =
        $(window).height() - $('#status').outerHeight() + 'px';
    _('folders').style.height =
        $('#left').outerHeight() - _.outerVSpace('#folders') + 'px';
    browser.fixFilesHeight();
    var width = $('#left').outerWidth() + $('#right').outerWidth();
    _('status').style.width = width + 'px';
    while ($('#status').outerWidth() > width)
        _('status').style.width = _.nopx(_('status').style.width) - 1 + 'px';
    while ($('#status').outerWidth() < width)
        _('status').style.width = _.nopx(_('status').style.width) + 1 + 'px';
    if ($.browser.msie && ($.browser.version.substr(0, 1) < 8))
        _('right').style.width = $(window).width() - $('#left').outerWidth() + 'px';
    _('files').style.width = $('#right').innerWidth() - _.outerHSpace('#files') + 'px';
    _('resizer').style.left = $('#left').outerWidth() - _.outerRightSpace('#folders', 'm') + 'px';
    _('resizer').style.width = _.outerRightSpace('#folders', 'm') + _.outerLeftSpace('#files', 'm') + 'px';
};

browser.fixFilesHeight = function() {
    _('files').style.height =
        $('#left').outerHeight() - $('#toolbar').outerHeight() - _.outerVSpace('#files') -
        (($('#settings').css('display') != "none") ? $('#settings').outerHeight() : 0) + 'px';
};

browser.showDialog = function(e) {
    this.shadow();
    if (e) {
        var left = e.pageX - parseInt($('#dialog').outerWidth() / 2);
        var top = e.pageY - parseInt($('#dialog').outerHeight() / 2);
        if (left < 15) left = 15;
        if (top < 15) top = 15;
        if (($('#dialog').outerWidth() + left) > $(window).width() - 30)
            left = $(window).width() - $('#dialog').outerWidth() - 15;
        if (($('#dialog').outerHeight() + top) > $(window).height() - 30)
            top = $(window).height() - $('#dialog').outerHeight() - 15;
        $('#dialog').css('left', left + "px");
        $('#dialog').css('top', top + "px");
    } else {
        $('#dialog').css('left', parseInt(($(window).width() - $('#dialog').outerWidth()) / 2) + 'px');
        $('#dialog').css('top', parseInt(($(window).height() - $('#dialog').outerHeight()) / 2) + 'px');
        $('#dialog').css('display', 'block');
    }

};

browser.hideDialog = function() {
    this.unshadow();
    if ($('#clipboard').hasClass('selected'))
        $('#clipboard').removeClass('selected');
    $('#dialog').css('display', 'none');
    $('div.folder > a > span.folder').removeClass('context');
    $('#dialog').html('');
};

browser.shadow = function() {
    $('#shadow').css('display', 'block');
};

browser.unshadow = function() {
    $('#shadow').css('display', 'none');
};

browser.showMenu = function(e) {
    var left = e.pageX;
    var top = e.pageY;
    if (($('#dialog').outerWidth() + left) > $(window).width())
        left = $(window).width() - $('#dialog').outerWidth();
    if (($('#dialog').outerHeight() + top) > $(window).height())
        top = $(window).height() - $('#dialog').outerHeight();
    $('#dialog').css('left', left + "px");
    $('#dialog').css('top', top + "px");
    $('#dialog').css('display', 'none');
    $('#dialog').fadeIn();
};

browser.fileNameDialog = function(e, post, inputName, inputValue, url, labels, callBack) {
    var html = '<form method="post" action="javascript:;">' +
        '<div class="box"><b>' + this.label(labels.title) + '</b><br />' +
        '<input name="' + inputName + '" value="' + _.htmlValue(inputValue) + '" type="text" /><br />' +
        '<div style="text-align:right">' +
        '<input type="submit" value="' + _.htmlValue(this.label("OK")) + '" />' +
        '<input type="button" value="' + _.htmlValue(this.label("Cancel")) + '" onclick="browser.hideDialog(); return false" />' +
    '</div></div></form>';
    $('#dialog').html(html);
    $('#dialog').unbind();
    $('#dialog').click(function() {
        return false;
    });
    $('#dialog form').submit(function() {
        var name = this.elements[0];
        name.value = $.trim(name.value);
        if (name.value == '') {
            alert(browser.label(labels.errEmpty));
            name.focus();
            return;
        } else if (/\//g.test(name.value)) {
            alert(browser.label(labels.errSlash))
            name.focus();
            return;
        } else if (name.value.substr(0, 1) == ".") {
            alert(browser.label(labels.errDot))
            name.focus();
            return;
        }
        eval('post.' + inputName + ' = name.value;');
        $.ajax({
            type: 'POST',
            url: url,
            data: post,
            async: false,
            success: function(xml) {
                if (browser.errors(xml)) return;
                if (callBack) callBack(xml);
                browser.hideDialog();
            },
            error: function(request, error) {
                alert(browser.label("Unknown error."));
            }
        });
        return false;
    });
    browser.showDialog(e);
    $('#dialog').css('display', 'block');
    $('#dialog input[type="submit"]').click(function() {
        return $('#dialog form').submit();
    });
    $('#dialog input[type="text"]').get(0).focus();
    $('#dialog input[type="text"]').get(0).select();
    $('#dialog input[type="text"]').keypress(function(e) {
        if (e.keyCode == 27) browser.hideDialog();
    });
};

browser.orderFiles = function(callBack, selected) {
    var order = _.kuki.get('order');
    var desc = (_.kuki.get('orderDesc') == 'on');

    browser.files = browser.files.sort(function(a, b) {
        var a1, b1, arr;
        if (!order) order = 'name';

        if (order == 'date') {
            a1 = a.mtime;
            b1 = b.mtime;
        } else if (order == 'type') {
            a1 = _.getFileExtension(a.name);
            b1 = _.getFileExtension(b.name);
        } else
            eval('a1 = a.' + order + '.toLowerCase(); b1 = b.' + order + '.toLowerCase();');

        if ((order == 'size') || (order == 'date')) {
            a1 = parseInt(a1 ? a1 : '');
            b1 = parseInt(b1 ? b1 : '');
            if (a1 < b1) return desc ? 1 : -1;
            if (a1 > b1) return desc ? -1 : 1;
        }

        if (a1 == b1) {
            a1 = a.name.toLowerCase();
            b1 = b.name.toLowerCase();
            arr = [a1, b1];
            arr = arr.sort();
            return (arr[0] == a1) ? -1 : 1;
        }

        arr = [a1, b1];
        arr = arr.sort();
        if (arr[0] == a1) return desc ? 1 : -1;
        return desc ? -1 : 1;
    });

    browser.showFiles(callBack, selected);
    browser.initFiles();
};

browser.humanSize = function(size) {
    if (size < 1024) {
        size = size.toString() + ' B';
    } else if (size < 1048576) {
        size /= 1024;
        size = parseInt(size).toString() + ' KB';
    } else if (size < 1073741824) {
        size /= 1048576;
        size = parseInt(size).toString() + ' MB';
    } else if (size < 1099511627776) {
        size /= 1073741824;
        size = parseInt(size).toString() + ' GB';
    } else {
        size /= 1099511627776;
        size = parseInt(size).toString() + ' TB';
    }
    return size;
};

browser.baseGetData = function(act) {
    var data = 'browse.php?type=' + this.type + '&lng=' + this.lang;
    if (act)
        data += "&act=" + act
    return data;
};

browser.label = function(index, data) {
    var label = this.labels[index] ? this.labels[index] : index;
    if (data)
        $.each(data, function(key, val) {
            label = label.replace('{' + key + '}', val);
        });
    return label;
};

browser.errors = function(xml) {
    if (!xml.getElementsByTagName('error').length)
        return false;
    var alertMsg = '';
    $.each(xml.getElementsByTagName('error'), function(i, error) {
        alertMsg += error.childNodes[0].nodeValue + "\n";
    });
    alertMsg = alertMsg.substr(0, alertMsg.length - 1);
    alert(alertMsg);
    return true;
};

browser.post = function(url, data) {
    var html = '<form id="postForm" method="POST" action="' + url + '">';
    $.each(data, function(key, val) {
        if ($.isArray(val))
            $.each(val, function(i, aval) {
                html += '<input type="hidden" name="' + _.htmlValue(key) + '[]" value="' + _.htmlValue(aval) + '" />';
            });
        else
            html += '<input type="hidden" name="' + _.htmlValue(key) + '" value="' + _.htmlValue(val) + '" />';
    });
    html += '</form>';
    $('#dialog').html(html);
    $('#dialog').css('display', 'block');
    $('#postForm').get(0).submit();
};

browser.fadeFiles = function() {
    $('#files > div').css('opacity', '0.4');
    $('#files > div').css('filter', 'alpha(opacity:40)');
};
browser.initSettings = function() {

    if (!this.shows.length) {
        var showInputs = $('#show input[type="checkbox"]').toArray();
        $.each(showInputs, function (i, input) {
            browser.shows[i] = input.name;
        });
    }

    var shows = this.shows;

    if (!_.kuki.isSet('showname')) {
        _.kuki.set('showname', 'on');
        $.each(shows, function (i, val) {
            if (val != "name") _.kuki.set('show' + val, 'off');
        });
    }

    $('#show input[type="checkbox"]').click(function() {
        var kuki = $(this).get(0).checked ? 'on' : 'off';
        _.kuki.set('show' + $(this).get(0).name, kuki)
        if ($(this).get(0).checked)
            $('#files .file div.' + $(this).get(0).name).css('display', 'block');
        else
            $('#files .file div.' + $(this).get(0).name).css('display', 'none');
    });

    $.each(shows, function(i, val) {
        var checked = (_.kuki.get('show' + val) == 'on') ? 'checked' : '';
        $('#show input[name="' + val + '"]').attr('checked', checked);
    });

    if (!this.orders.length) {
        var orderInputs = $('#order input[type="radio"]').toArray();
        $.each(orderInputs, function (i, input) {
            browser.orders[i] = input.value;
        });
    }

    var orders = this.orders;

    if (!_.kuki.isSet('order'))
        _.kuki.set('order', 'name');

    if (!_.kuki.isSet('orderDesc'))
        _.kuki.set('orderDesc', 'off');

    $('#order input[value="' + _.kuki.get('order') + '"]').attr('checked', 'checked');
    $('#order input[name="desc"]').attr('checked',
        (_.kuki.get('orderDesc') == 'on') ? 'checked' : ''
    );

    $('#order input[type="radio"]').click(function() {
        _.kuki.set('order', $(this).get(0).value);
        browser.orderFiles();
    });

    $('#order input[name="desc"]').click(function() {
        _.kuki.set('orderDesc', $(this).get(0).checked ? "on" : "off");
        browser.orderFiles();
    });

    if (!_.kuki.isSet('view'))
        _.kuki.set('view', 'thumbs');

    if (_.kuki.get('view') == "list") {
        $('#show input').attr('checked', 'checked');
        $('#show input').attr('disabled', 'disabled');
    }

    $('#view input[value="' + _.kuki.get('view') + '"]').attr('checked', 'checked');

    $('#view input').click(function() {
        var view = $(this).attr('value');
        if (_.kuki.get('view') != view) {
            _.kuki.set('view', view);
            if (view == 'list') {
                $('#show input').attr('checked', 'checked');
                $('#show input').attr('disabled', 'disabled');
            } else {
                $.each(browser.shows, function(i, val) {
                    if (_.kuki.get('show' + val) != "on")
                        $('#show input[name="' + val + '"]').attr('checked', '');
                });
                $('#show input').attr('disabled', '');
            }
        }
        browser.refresh();
    });
};

browser.initToolbar = function() {
    $('#toolbar a').click(function() {
        browser.hideDialog();
    });

    if (!_.kuki.isSet('displaySettings'))
        _.kuki.set('displaySettings', 'off');

    if (_.kuki.get('displaySettings') == 'on') {
        $('#toolbar a[href="kcact:settings"]').addClass('selected');
        $('#settings').css('display', 'block');
        browser.resize();
    }

    $('#toolbar a[href="kcact:settings"]').click(function () {
        if ($('#settings').css('display') == 'none') {
            $(this).addClass('selected');
            _.kuki.set('displaySettings', 'on');
            $('#settings').css('display', 'block');
            browser.fixFilesHeight();
        } else {
            $(this).removeClass('selected');
            _.kuki.set('displaySettings', 'off');
            $('#settings').css('display', 'none');
            browser.fixFilesHeight();
        }
        return false;
    });

    $('#toolbar a[href="kcact:refresh"]').click(function() {
        browser.refresh();
        return false;
    });

    if (window.opener || this.opener.TinyMCE || $('iframe', window.parent.document).get(0))
        $('#toolbar a[href="kcact:maximize"]').click(function() {
            browser.maximize(this);
            return false;
        });
    else
        $('#toolbar a[href="kcact:maximize"]').css('display', 'none');

    $('#toolbar a[href="kcact:about"]').click(function() {
        var html = '<div class="box about">' +
            '<div class="title"><a href="http://kcfinder.sunhater.com" target="_blank">KCFinder 2.1</a></div>' +
            '<div>Licenses: GPLv2 & LGPLv2</div>' +
            '<div>Copyright &copy;2010 Pavel Tzonkov</div>' +
            '<button>' + _.htmlValue(browser.label("OK")) + '</button>' +
        '</div>';
        $('#dialog').html(html);
        browser.showDialog();
        $('#dialog button').get(0).focus();
        var close = function() {
            browser.hideDialog();
            browser.unshadow();
        }
        $('#dialog button').click(close);
        $('#dialog button').keypress(function(e) {
            if (e.keyCode == 27) close();
        });
        $('#dialog').unbind();
        return false;
    });

    this.initUploadButton();
};

browser.initUploadButton = function() {
    var btn = $('#toolbar a[href="kcact:upload"]');
    var top = btn.get(0).offsetTop;
    var width = btn.outerWidth();
    var height = btn.outerHeight();
    $('#toolbar').prepend('<div id="upload" style="top:' + top + 'px;width:' + width + 'px;height:' + height + 'px">' +
        '<form enctype="multipart/form-data" method="post" target="uploadResponse" action="' + browser.baseGetData('upload') + '">' +
            '<input type="file" name="upload" onchange="browser.uploadFile(this.form)" style="height:' + height + 'px" />' +
            '<input type="hidden" name="dir" value="" />' +
        '</form>' +
    '</div>');
    $('#upload input').css('margin-left', "-" + ($('#upload input').outerWidth() - width) + "px");
    $('#upload').mouseover(function() {
        $('#toolbar a[href="kcact:upload"]').addClass('hover');
    });
    $('#upload').mouseout(function() {
        $('#toolbar a[href="kcact:upload"]').removeClass('hover');
    });
};

browser.uploadFile = function(form) {
    if (!this.dirWritable) {
        alert(this.label("Cannot write to upload folder."));
        $('#upload').detach();
        browser.initUploadButton();
        return;
    }
    form.elements[1].value = browser.dir;
    $('<iframe id="uploadResponse" name="uploadResponse" src="javascript:;"></iframe>').prependTo(document.body);
    $('#loading').html(this.label("Uploading file..."));
    $('#loading').css('display', 'inline');
    form.submit();
    $('#uploadResponse').load(function() {
        var response = $(this).contents().find('body').html();
        $('#loading').css('display', 'none');
        if (response.length && response.substr(0, 1) != '/')
            alert(response);
        else
            browser.refresh(response.substr(1, response.length - 1));
        $('#upload').detach();
        setTimeout(function() {
            $('#uploadResponse').detach();
        }, 1);
        browser.initUploadButton();
    });
};

browser.maximize = function(button) {
    if (window.opener) {
        window.moveTo(0, 0);
        width = screen.availWidth;
        height = screen.availHeight;
        if ($.browser.opera)
            height -= 50;
        window.resizeTo(width, height);

    } else if (browser.opener.TinyMCE) {
        var win, ifr, id;

        $('iframe', window.parent.document).each(function() {
            if (/^mce_\d+_ifr$/.test($(this).attr('id'))) {
                id = parseInt($(this).attr('id').replace(/^mce_(\d+)_ifr$/, "$1"));
                win = $('#mce_' + id, window.parent.document);
                ifr = $('#mce_' + id + '_ifr', window.parent.document);
            }
        });

        if ($(button).hasClass('selected')) {
            $(button).removeClass('selected');
            win.css('left', browser.maximizeMCE.left + 'px');
            win.css('top', browser.maximizeMCE.top + 'px');
            win.css('width', browser.maximizeMCE.width + 'px');
            win.css('height', browser.maximizeMCE.height + 'px');
            ifr.css('width', browser.maximizeMCE.width - browser.maximizeMCE.Hspace + 'px');
            ifr.css('height', browser.maximizeMCE.height - browser.maximizeMCE.Vspace + 'px');

        } else {
            $(button).addClass('selected')
            browser.maximizeMCE = {
                width: _.nopx(win.css('width')),
                height: _.nopx(win.css('height')),
                left: win.position().left,
                top: win.position().top,
                Hspace: _.nopx(win.css('width')) - _.nopx(ifr.css('width')),
                Vspace: _.nopx(win.css('height')) - _.nopx(ifr.css('height'))
            };
            var width = $(window.parent).width();
            var height = $(window.parent).height();
            win.css('left', $(window.parent).scrollLeft() + 'px');
            win.css('top', $(window.parent).scrollTop() + 'px');
            win.css('width', width + 'px');
            win.css('height', height + 'px');
            ifr.css('width', width - browser.maximizeMCE.Hspace + 'px');
            ifr.css('height', height - browser.maximizeMCE.Vspace + 'px');
        }

    } else if ($('iframe', window.parent.document).get(0)) {
        var ifrm = $('iframe[name="' + window.name + '"]', window.parent.document);
        var parent = ifrm.parent();
        var width, height;
        if ($(button).hasClass('selected')) {
            $(button).removeClass('selected');
            if (browser.maximizeThread) {
                clearInterval(browser.maximizeThread);
                browser.maximizeThread = null;
            }
            if (browser.maximizeW) browser.maximizeW = null;
            if (browser.maximizeH) browser.maximizeH = null;
            $.each($('*', window.parent.document).get(), function(i, e) {
                e.style.display = browser.maximizeDisplay[i];
            });
            ifrm.css('display', browser.maximizeCSS.display);
            ifrm.css('position', browser.maximizeCSS.position);
            ifrm.css('left', browser.maximizeCSS.left);
            ifrm.css('top', browser.maximizeCSS.top);
            ifrm.css('width', browser.maximizeCSS.width);
            ifrm.css('height', browser.maximizeCSS.height);
            $(window.parent).scrollLeft(browser.maximizeLest);
            $(window.parent).scrollTop(browser.maximizeTop);

        } else {
            $(button).addClass('selected');
            browser.maximizeCSS = {
                display: ifrm.css('display'),
                position: ifrm.css('position'),
                left: ifrm.css('left'),
                top: ifrm.css('top'),
                width: ifrm.outerWidth() + 'px',
                height: ifrm.outerHeight() + 'px'
            };
            browser.maximizeTop = $(window.parent).scrollTop();
            browser.maximizeLeft = $(window.parent).scrollLeft();
            browser.maximizeDisplay = [];
            $.each($('*', window.parent.document).get(), function(i, e) {
                browser.maximizeDisplay[i] = $(e).css('display');
                $(e).css('display', 'none');
            });

            ifrm.css('display', 'block');
            ifrm.parents().css('display', 'block');
            var resize = function() {
                width = $(window.parent).width();
                height = $(window.parent).height();
                if (!browser.maximizeW || (browser.maximizeW != width) ||
                    !browser.maximizeH || (browser.maximizeH != height)
                ) {
                    browser.maximizeW = width;
                    browser.maximizeH = height;
                    ifrm.css('width', width + 'px');
                    ifrm.css('height', height + 'px');
                    browser.resize();
                }
            }
            ifrm.css('position', 'absolute');
            if ((ifrm.offset().left == ifrm.position().left) &&
                (ifrm.offset().top == ifrm.position().top)
            ) {
                ifrm.css('left', '0');
                ifrm.css('top', '0');
            } else {
                ifrm.css('left', - ifrm.offset().left +'px');
                ifrm.css('top', - ifrm.offset().top + 'px');
            }
            resize();
            browser.maximizeThread = setInterval(resize, 250);
        }
    }
};

browser.refresh = function(selected) {
    this.fadeFiles();
    $.ajax({
        type: 'POST',
        url: browser.baseGetData('chDir'),
        data: {dir:browser.dir},
        async: false,
        success: function(xml) {
            if (browser.errors(xml)) return;
            var files = xml.getElementsByTagName('file');
            var dirWritable =
                xml.getElementsByTagName('files')[0].getAttribute('dirWritable');
            browser.dirWritable = (dirWritable == 'yes');
            browser.loadFiles(files);
            browser.orderFiles(null, selected);
            browser.statusDir();
        },
        error: function(request, error) {
            $('#files > div').css({opacity:'', filter:''});
            $('#files').html(browser.label("Unknown error."));
        }
    });
};
