function FileMan() {
    this.config = {
        timer     : 750,
        uploadmax_width : 400,
        wrapper   : 0,
        content   : 0,
        effect    : true,
        image_url : null,
        cgi_url   : null,
        root_path : null,
        regnum    : '',
        work_path : '/'
    };
    this.current = {
        command : null,
        action  : null
    };
    this.height      = {
        contentmessage : $('#contentmessage').outerHeight(),
        wrapperheader  : $('#wrapper-header').outerHeight() + 4,
        wrapperfooter  : $('#wrapper-footer').outerHeight()
    };
/* Field maps */
    this.maps   = { type: 0, icon: 1, name: 2, size: 3, desc: 4, date: 5, owner: 6, perm: 7, sperm: 8, sdate: 9, path: 10, full_path: 11 };
/* Paging variables */
    this.paging = {
        num_hits    : 0,
        current_page: 1,
        size        : '',
        max_hits    : 25,
        sb          : 'name',
        so          : 'asc'
    };
    this.files = new Array(); this.paths = new Array();
    this.hiddens = new Object(); this.cdata = new Object();
    this.parent = '';
    
/* Form object */
    this.form  = $('#wrapper-content form');
/* Screen dimensions */
    this.screen = {
        height : getScreenHeight(),
        width : getScreenWidth()
    };
/* Languages which shows up in status bar */
    this.languages = {
      preferences : 'Preferences',
      setup : 'Setup',
      password : 'Change Password',
      user : 'User Management',
      log : 'Browser Logs',
      env : 'Environment',
      user_add : 'Add a user',
      user_modify : 'Modify a user',
      user_access : 'Change accesses',
      user_permission : 'Change Permissions',
      uncompress : 'Uncompress'
    };
    this.fileEditor = new Object();
    var fm = this;
    this.config.tinyMCE = {
        // General options
        id : 'tinyEditor',
        mode : "textareas",
        theme : "advanced",
        plugins : "style,table,advhr,advimage,advlink,preview,media,searchreplace,fullpage",
        convert_urls : false,
        remove_linebreaks : false,
        setup : function(ed) {
            ed.onChange.add(function(ed, l) {
                if (!fm.fileEditor.beingEdited) fm.fileEditor.beingEdited = true;
            });
        },
        // Theme options
        theme_advanced_buttons1 : "newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,image,cleanup,help,|,forecolor,backcolor",
        theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,|,sub,sup,|,charmap,iespell,media,advhr,|,code,preview,|,fullpage",
        theme_advanced_resizing : true,
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "left",
        theme_advanced_statusbar_location : "bottom"
    };
}
/*
    Initial setting variables and actions    
*/
FileMan.prototype.init = function() {
    var fm = this;
    var $modal = $('#modal-dialog');
/* Set up the commands */
    $('#primarynav a[rel]').each(function() {
        $(this).click(function() {
            var action = $(this).attr('rel')
            if ($(this).parent().hasClass('navitem')) {
                if ($('#cmd-' + action).length == 1) {
                    if (action == 'file') {
                        fm.newfile();
                    }
                    else {
                        fm.commandDialog({ command : action });
                    }
                }
            }
            else if (action == 'help') {
                fm.help();
            }
            else if (action == 'about') {
                fm.about();
            }
            else {
                fm.actionForm(action);
            }
            return false;
        });
    });
/* The layout should be resized when window is resized */
    $(window).resize(function() {
        fm.screen = {
            height : getScreenHeight(),
            width : getScreenWidth()
        };       
        if (!$modal.hasClass('hidden')) {
            var mwidth = $modal.width();
            var mleft  = parseInt((fm.screen.width - mwidth) / 2);
            $modal.css('left', mleft + 'px');
        }
        fm.layoutDimensions(fm.screen.height);
    });
/* Set up CD form */
    $('#cdform form').submit(function() {
        fm.cd({ dname : $(this).find('input[name="dname"]').val() });
        $(this).resetForm();
        return false;
    });
    this.form.append('').submit(function() {
        var command = fm.current.command || fm.current.action;
/* Handle extra steps if needed for some commands before submit the request */
        fm.form.attr('action', fm.config.cgi_url);
        if (command == 'command') {
            fm.command();
        }
        else if (command == 'upload') {
            fm.upload();
        }
        else if (command.search(/file|edit/) == 0) {
            if (tinyMCE.activeEditor) {
                var editor  = $('textarea[name="editor"]');
                var content = $('#editor_mode').val() == 'html' ? fm.tinyMCEContent() : editor.val();
                tinyMCE.activeEditor.remove();
                editor.val(content);
            }
        }
        $(this).ajaxSubmit({
            dataType : 'json',
            beforeSubmit : function() {
                /* Display waiting image for some commands */
                if (command.search(/search|replace|uncompress|compress|copy|delete|move|download/) == 0) {
                  fm.loading('start');
                }
            },
            success : function(response) {
                fm.loading('end');
                if (response.status == 'ERR_NOAUTH') {
                    fm.login(response.data.html);
                }
                else {
                    fm.commandResponse(response);
                }
            }
        });
        return false;
    });
/* Load files and setting layout */
    this.cd({ load_default : 1 });
    this.layoutDimensions();
/* Set up sorting action for the headers */
    $('.foldertab th a[rel]').each(function() {
        var link = $(this);
        link.click(function() {
            $('.foldertab th a[rel] img').remove();
            if (fm.paging.sb != link.attr('rel')) {
                fm.paging.sb = link.attr('rel');
                fm.paging.so = fm.paging.sb.search(/date|size|perm/) != -1 ? 'desc' : 'asc';
            }
            else {
                fm.paging.so = fm.paging.so == 'asc' ? 'desc' : 'asc';
            }
            fm.sort(fm.files, fm.paging.sb, fm.paging.so);
            fm.page(fm.paging, function(nh) { fm.printFiles(nh); });
            return false;
        });
    });
/* Set Advance search and upload multiple files link */
    this.form.find('a[rel="advance-search"]').click(function() { return fm.advanceSearch(); });
    this.form.find('a[rel="upload-multiple"]').click(function() { return fm.uploadFiles(); });
/* Set action for action drop down */
    $('#fm_action').attr('selectedIndex', 0).change(function() {
        var action = $(this).val();
        if ($('#cmd-' + action).length == 1 || action == '' || action.search(/delete|perl|print/) == 0) {
            fm.actionDialog({ action : action });
        }
        else {
            fm.showMessage({ success : false, message : 'Invalid action: ' + action });
        }
    });
/* Cluetip setup */
    $('.help').cluetip({
        activation : 'click',
        closePosition : 'title',
        closeText: ' ',
        width : 400,
        height : 300,
        sticky : true,
        arrows : false
    });
/* Handle showing sub-menus */
    if (this.config.is_ie) {
        $('.primarynav li[class="navitem"]').each(function() {
            var $li = $(this);
            if ($li.find('ul').length == 0) return;
            var $ul = $li.find('ul');
            $li.mouseover(function() {
                $li.addClass('sfhover');
                $li.append('');
            });
            $li.mouseout(function() {
                $li.find('iframe').remove();
                $li.removeClass('sfhover');
            });
        });
    }
/* Search Expression option requires 'Search Contents' checked */
    $('#search_exp').click(function() {
        $('#search_content').attr('checked', $(this).attr('checked') ? true : false);
    })
/* Browse buttons */
    $('input[name="button-browse"]').each(function() {
        var button = $(this);
        button.click(function() {
            var command = fm.current.command || fm.current.action;
            fm.browse({
                title : command == 'diff' ? 'Select a text file' : 'Select Directory',
                filter : command == 'diff' ? 2 : 1,
                hidden_query : fm.hiddens.hidden_query,
                id : command + '_input'
            });
        });
    });
/* Setting for chmod command */
    $('#cmd-chmod input[name="chmod_input"]').change(function() {
        var val = $(this).val();
        if (val.length == 0) return;
        if (val.search(/\D/) >= 0) {
            $(this).val('').focus();
            fm.showMessage({ success : false, message : 'Invalid octal notation.'})
            return;
        }        
        var nums = val.split("");
        var invalid = false;
        for (var i=0; i
',
        width : 400,
        height : 300,
        sticky : true,
        arrows : false
    });
/* Handle showing sub-menus */
    if (this.config.is_ie) {
        $('.primarynav li[class="navitem"]').each(function() {
            var $li = $(this);
            if ($li.find('ul').length == 0) return;
            var $ul = $li.find('ul');
            $li.mouseover(function() {
                $li.addClass('sfhover');
                $li.append('');
            });
            $li.mouseout(function() {
                $li.find('iframe').remove();
                $li.removeClass('sfhover');
            });
        });
    }
/* Search Expression option requires 'Search Contents' checked */
    $('#search_exp').click(function() {
        $('#search_content').attr('checked', $(this).attr('checked') ? true : false);
    })
/* Browse buttons */
    $('input[name="button-browse"]').each(function() {
        var button = $(this);
        button.click(function() {
            var command = fm.current.command || fm.current.action;
            fm.browse({
                title : command == 'diff' ? 'Select a text file' : 'Select Directory',
                filter : command == 'diff' ? 2 : 1,
                hidden_query : fm.hiddens.hidden_query,
                id : command + '_input'
            });
        });
    });
/* Setting for chmod command */
    $('#cmd-chmod input[name="chmod_input"]').change(function() {
        var val = $(this).val();
        if (val.length == 0) return;
        if (val.search(/\D/) >= 0) {
            $(this).val('').focus();
            fm.showMessage({ success : false, message : 'Invalid octal notation.'})
            return;
        }        
        var nums = val.split("");
        var invalid = false;
        for (var i=0; i ',
                        width : 400,
                        height : 300,
                        sticky : true,
                        arrows : false
                    });
                });          
            });
        });
        this.showStatus(this.languages[action] || action);
    }
    if (!$contentheader.is(':hidden')) {
        this.fadeOut($('#cmd-' + this.current.command), function() {
            fm.animate($("#ocwrapper"), {
                'margin-top' : 0,
                'height'     : fm.height.wrapper
            }, 'normal', function() {
                fm.animate($("#content"), { height: fm.height.content });
                $contentframe.css('height', fm.height.content - toolbar_height + 'px');
                fm.fadeOut($contentheader, function() {
                    $('#' + action + '_input').focus();
                });
            });
        });
        this.current.command = null;
        $('.primarynav a[rel]').parent().removeClass('selected');
    }
    else if (!html) {
        this.animate($("#content"), { height: fm.height.content });
        $contentframe.css('height', fm.height.content - toolbar_height + 'px');
    }
/* Reset form before display it */
    this.resetForm(action);
/* Show action form if applicated */
    if (this.current.action && this.current.action != 'delete') {
        this.fadeOut($('#cmd-' + this.current.action), function() {
            fm.fadeIn($('#cmd-' + action), function () {
                $('#' + action + '_input').focus();
            });
        });
    }
    else {
        this.fadeIn($('#cmd-' + action), function () {
            $('#' + action + '_input').focus();
        });
    }
/* Save the action */
    this.current.action = action;
    $('#cmd').val(action)
    this.form.find('input[name="confirm-name"]').val('');
    /* Handle specific action */
    if (this.current.action.search(/delete|perl|print/) == 0) {
        this.form.submit();
    }
    else if (this.current.action == 'chmod') {
        $('#cmd-chmod .checkbox').click(function() {
            fm.chmod();
        });
        /* Loading permission for a file if selected */
        var fselected = $('input[name="cinput"][checked]');
        if (fselected.length > 0) {
            var fname = fselected.length == 1 ? fselected.val() : $(fselected[0]).val();
            this.parsePerm(fname);
        }
    }
    else if (this.current.action == 'tail') {
        $('#' + this.current.action + '_input').val('25');
    }  
}
/*
  commandReponse method handles output of a command
  json: should be json data object
*/
FileMan.prototype.commandResponse = function(json) {
    var command = this.current.command || this.current.action;
    var fm = this;
    this.form.find('input[name="confirm-name"]').val('');
    if (command.search(/search|replace/) != -1) { /* The search command returns */
        this.paging.num_hits = json.data.hits;
        this.paging.size     = json.data.size;
        this.readme          = '';
        /* Displaying search results, paging, and status info */
        this.sort(json.data.files, this.paging.sb, this.paging.so);
        this.page(this.paging, function(nh) { fm.printFiles(nh); });
        if (json.success) this.showStatus();
        this.form.append(''); 
        this.showMessage(json);
    }
    else if (json.data.confirm == 1 && json.data.file) {
        this.modalConfirm({
            html : 'Do you want to overwrite ' + json.data.file.name + '?',
            yes : function($modal) {
                fm.form.append('').submit();
                $modal.html('').jqmHide();
            },
            no : function($modal) {
                $modal.html('').jqmHide();
            }
        });
    }
    else if (command.search(/copy|move/) == 0) {
        this.copy(json);
    }
    else if (command == 'delete') {
        this.remove(json);
    }
    else if (command == 'print') {
        this.print(json);
    }
    else if (command == 'download') {
        if (json.success) {
            this.preview(json.data.file, 'download');
        }
        else {
            this.showMessage(json);
        }
    }
    else if (command == 'perl') {
        this.perl(json);
    }
    else if (command.search(/diff|tail/) == 0) {
        if (json.success) {
            this.showStatus(command);
            this.actionResponse('
',
                        width : 400,
                        height : 300,
                        sticky : true,
                        arrows : false
                    });
                });          
            });
        });
        this.showStatus(this.languages[action] || action);
    }
    if (!$contentheader.is(':hidden')) {
        this.fadeOut($('#cmd-' + this.current.command), function() {
            fm.animate($("#ocwrapper"), {
                'margin-top' : 0,
                'height'     : fm.height.wrapper
            }, 'normal', function() {
                fm.animate($("#content"), { height: fm.height.content });
                $contentframe.css('height', fm.height.content - toolbar_height + 'px');
                fm.fadeOut($contentheader, function() {
                    $('#' + action + '_input').focus();
                });
            });
        });
        this.current.command = null;
        $('.primarynav a[rel]').parent().removeClass('selected');
    }
    else if (!html) {
        this.animate($("#content"), { height: fm.height.content });
        $contentframe.css('height', fm.height.content - toolbar_height + 'px');
    }
/* Reset form before display it */
    this.resetForm(action);
/* Show action form if applicated */
    if (this.current.action && this.current.action != 'delete') {
        this.fadeOut($('#cmd-' + this.current.action), function() {
            fm.fadeIn($('#cmd-' + action), function () {
                $('#' + action + '_input').focus();
            });
        });
    }
    else {
        this.fadeIn($('#cmd-' + action), function () {
            $('#' + action + '_input').focus();
        });
    }
/* Save the action */
    this.current.action = action;
    $('#cmd').val(action)
    this.form.find('input[name="confirm-name"]').val('');
    /* Handle specific action */
    if (this.current.action.search(/delete|perl|print/) == 0) {
        this.form.submit();
    }
    else if (this.current.action == 'chmod') {
        $('#cmd-chmod .checkbox').click(function() {
            fm.chmod();
        });
        /* Loading permission for a file if selected */
        var fselected = $('input[name="cinput"][checked]');
        if (fselected.length > 0) {
            var fname = fselected.length == 1 ? fselected.val() : $(fselected[0]).val();
            this.parsePerm(fname);
        }
    }
    else if (this.current.action == 'tail') {
        $('#' + this.current.action + '_input').val('25');
    }  
}
/*
  commandReponse method handles output of a command
  json: should be json data object
*/
FileMan.prototype.commandResponse = function(json) {
    var command = this.current.command || this.current.action;
    var fm = this;
    this.form.find('input[name="confirm-name"]').val('');
    if (command.search(/search|replace/) != -1) { /* The search command returns */
        this.paging.num_hits = json.data.hits;
        this.paging.size     = json.data.size;
        this.readme          = '';
        /* Displaying search results, paging, and status info */
        this.sort(json.data.files, this.paging.sb, this.paging.so);
        this.page(this.paging, function(nh) { fm.printFiles(nh); });
        if (json.success) this.showStatus();
        this.form.append(''); 
        this.showMessage(json);
    }
    else if (json.data.confirm == 1 && json.data.file) {
        this.modalConfirm({
            html : 'Do you want to overwrite ' + json.data.file.name + '?',
            yes : function($modal) {
                fm.form.append('').submit();
                $modal.html('').jqmHide();
            },
            no : function($modal) {
                $modal.html('').jqmHide();
            }
        });
    }
    else if (command.search(/copy|move/) == 0) {
        this.copy(json);
    }
    else if (command == 'delete') {
        this.remove(json);
    }
    else if (command == 'print') {
        this.print(json);
    }
    else if (command == 'download') {
        if (json.success) {
            this.preview(json.data.file, 'download');
        }
        else {
            this.showMessage(json);
        }
    }
    else if (command == 'perl') {
        this.perl(json);
    }
    else if (command.search(/diff|tail/) == 0) {
        if (json.success) {
            this.showStatus(command);
            this.actionResponse('' + json.data.output + '
');
            $('#' + command + '_input').focus();
            /* Handle refreshing for tail command if enabled */
            if (command == 'tail' && json.data.refresh > 0) {
                this.timerID = window.setTimeout(function() { fm.form.submit(); }, json.data.refresh * 1000);
            }
        }
        else {
            if (this.timerID) window.clearTimeOut(this.timerID);    
            this.showMessage(json);
        }
    }
    else if (command.search(/user/) == 0) {
        if (json.success == true) {
            this.actionDialog({ action : 'user', json : json });
        }
        else if (json.message) {
            this.showMessage(json);
            $('#user_action').val('');
        }
    }
    else if (command == 'logout') {
      this.login(json.data.html);
    }
    else {
        if (command == 'upload') $('#modal-dialog').jqm().jqmHide();
        if (json.success) {
            /* Overwrite preferences */
            if (command == 'preferences') {
                this.config.effect    = json.data.defaults.effect == 1 ? true : false;
                this.config.readme    = json.data.defaults.readme;
                this.paging.max_hits  = json.data.defaults.maxhits;
                this.paging.sb        = json.data.defaults.sb || 'name';
                this.paging.so        = json.data.defaults.so || 'asc';
            }
            var callback = this.fileEditor.callback;
            var edited   = this.fileEditor.beingEdited;
            var action_called = this.fileEditor.actionCalled;
            /* Re-load file list */
            this.fileEditor = new Object();
            if (action_called != true) {
                if (command == 'uncompress') this.commandDialog({ success : json.success, message : json.message, refresh : true });
                else this.cd(json);
                this.resetForm(command);
            }
            /* Excutive editor's callback if available */
            if (edited && typeof(callback) == 'function') {
                callback();
            }
        }
        else if (json.message) {
            this.showMessage(json);
        }        
    }
}
/* 
  actionResponse method handles displaying the result of actions that aren't requried 'submit' button hit
    (e.g.: delete, perl, print...)
  html : should be html code
*/
FileMan.prototype.actionResponse = function(html) {
    this.form.append('');
    if ($('#command-dialog').length == 0) {
        var contentframe_height = this.height.content - this.height.toolbar + this.height.folder;
        this.fadeOut($('.paging'));
        this.fadeOut($('.readme'));
        this.fadeOut($('.foldertab'), function() { $(".contentframe").css('height', contentframe_height + 'px'); });
        $('.contentframe').append('');
    }
    this.fadeIn($('#command-dialog').html(html));
}
/*
  actionForm method prints out a action form.
  action : should be an action
  args   : should be a hash of all parameters that are passed in.
*/
FileMan.prototype.actionForm = function(action, args) {
    var fm = this;
    this.printForm(action, function (response) {
        if (response.success) {
            fm.actionDialog({ action : action, json : response });
        }
        else if (response.message) {
            fm.showMessage(response);
        }
    }, args);
}
/* 
  uploadFiles : allows multiple files uploading
*/
FileMan.prototype.uploadFiles = function() {
    var $modal = $('#modal-dialog');
    var html   = '';
    var mwidth = 650;
    var mleft  = parseInt(($(window).width() - mwidth) / 2);
    $modal.jqm().removeClass().addClass('modal-dialog modal-dialog-form')
        .css('width', mwidth + 'px').css('left', mleft + 'px').css('top', '20%')
        .html(html).jqmShow();
    var fm = this;
    $modal.find('a[rel="addfile"]').click(function() {
        var uploads = $modal.find('input[type="file"]');
        if (uploads.length == fm.config.max_upload) return false;
        if (uploads.length < fm.config.max_upload) {
            $('#upfiles').append('';
        for (var i=0; i
' + htmlEscape(output) + ''); /* Clear timer ID */ window.clearTimeout(fm.timerID); fm.timerID = 0; $.ajax({ type : 'GET', dataType : 'xml', cache : false, url : fm.config.cgi_url + '?cmd=command;serial=' + fm.config.serial + ';remove=1;ajax=1' + fm.hiddens.hidden_query }); } else { $('#' + random_str).html('
' + output + ''); fm.timerID = window.setTimeout(function() { fm.commandProgress(random_str, input); }, 500); } } }); } /* List information about the files of a directory args : should be a hash of all options func : should be a callback function. */ FileMan.prototype.ls = function(args, func) { if (!args) args = new Object(); var dname = args.dname || ''; var html = ''; var $form = $('#cdbar').append(html).find('#tmpform'); if (args.breadcrumbs) $form.find('input[name="work_path"]').val(''); var params = new Array('load_default', 'filter', 'a'); for (var i=0; i
 ').jqmShow();
        });
    }
    else {
        this.timer = false;
        if (!$('#waiting-dialog').is(':hidden')) $('#waiting-dialog').html('').jqmHide();
    }
}
/*
  cd command
  args : should be a hash of
    dname : should be directory name where you want to cd to
    breadcrumbs : should be true/false. work_path will be set to null if it's true
    work_path : should be true/false
*/
FileMan.prototype.cd = function(args) {
    if (!args) args = new Object();
    this.loading('start');
    var success = args.success;
    var fm = this;
    this.ls(args, function(response) {
        if (response.success) {
            fm.paging.num_hits     = response.data.hits;
            fm.paging.size         = response.data.size;
            fm.paging.current_page = 1;
            fm.hiddens             = response.data.hiddens;
            fm.readme              = response.data.readme_content;
            if (response.data.root_path) fm.config.root_path = response.data.root_path;
            $('#hiddens').empty().append(fm.hiddens.hidden_objects);
            if (response.data.paths) {         
                fm.paths  = response.data.paths.loop;
                fm.parent = response.data.paths.parent;
                fm.config.work_path = response.data.paths.work_path;
            }
            else {
                fm.paths  = new Array();
                fm.parent = '';
                fm.config.work_path = '/';
            }
            /* Print out the list of files, sorting, bread crumbs, paging */
            fm.sort(response.data.files, fm.paging.sb, fm.paging.so);
            fm.breadCrumbs();
            fm.page(fm.paging, function(nh) { fm.printFiles(nh); });
            fm.showStatus();
            $('#cdform input[name="dname"]').focus();   
            if ($('#listfiles').is(':hidden') || $('.foldertab').is(':hidden')) {
                fm.commandDialog(args);
            }
            else if (!success && !$('#contentmessage').is(':hidden')) {
                fm.hideMessage();
            }
            else if (success) {
                fm.showMessage(args);
            }
            fm.htaccess(response.data.htaccess_users);
        }
        else {
            fm.showMessage(response);
        }
       fm.loading('end');
    });
}
/*
  modalConfirm show a modal confirm dialog
  args : should be a hash of all actions
  e.g. 
  object.modalConfirm({
    data : 'json data object',
    yes : function($modal) {
      Do something here..
    },
    no : function($modal) {
      blah blah..
    }
    ....
  });
*/
FileMan.prototype.modalConfirm = function(args) {
    var $modal  = $('#modal-dialog');
    var html    = '';
    var nwidth = 400;
    var nleft  = parseInt($(window).width() - nwidth) /2;
    $modal.jqm().removeClass().addClass('modal-dialog modal-dialog-form modal-confirm')
        .css('left', nleft + 'px').css('top', '30%').css('width', nwidth + 'px')
        .html(html).jqmShow().find('input[type="button"]').click(function() {
        var name = $(this).attr('name');
        if (name == 'button-yes' && typeof(args.yes) == 'function') args.yes($modal);
        else if (name == 'button-all' && typeof(args.all) == 'function') args.all($modal);
        else if (name == 'button-skip' && typeof(args.skip) == 'function') args.skip($modal);
        else if (name == 'button-no' && typeof(args.no) == 'function') args.no($modal);
        else if (name == 'button-cancel' && typeof(args.cancel) == 'function') args.cancel($modal);
    });
    var fm = this;
    $modal.find('h1 img').css('cursor', 'pointer').click(function() { 
        $('select[class="action"]').val('');
        fm.current.action = '';
        $modal.jqmHide();
    });
    $modal.find('form').ajaxForm({
        dataType: 'json',
        success : function(data) {
            fm.commandResponse(data);
        }
    });
}
/*
  printFiles method handles files listing
  nh : should be a page number
*/
FileMan.prototype.printFiles = function(nh) {
    if (typeof(nh) == 'undefined') nh = 1;
    var beg   = nh == 1 ? 0 : ((nh - 1) * this.paging.max_hits);
    var $body = $('.contentframe table[class="foldertab"]');
    $body.empty();
    $('.readme').remove();
    var count = 0;
    var array = '';
    var maps  = this.maps;
    /* Print out parent link */
    if (this.parent != '') {
        var tr = '
').jqmShow();
        });
    }
    else {
        this.timer = false;
        if (!$('#waiting-dialog').is(':hidden')) $('#waiting-dialog').html('').jqmHide();
    }
}
/*
  cd command
  args : should be a hash of
    dname : should be directory name where you want to cd to
    breadcrumbs : should be true/false. work_path will be set to null if it's true
    work_path : should be true/false
*/
FileMan.prototype.cd = function(args) {
    if (!args) args = new Object();
    this.loading('start');
    var success = args.success;
    var fm = this;
    this.ls(args, function(response) {
        if (response.success) {
            fm.paging.num_hits     = response.data.hits;
            fm.paging.size         = response.data.size;
            fm.paging.current_page = 1;
            fm.hiddens             = response.data.hiddens;
            fm.readme              = response.data.readme_content;
            if (response.data.root_path) fm.config.root_path = response.data.root_path;
            $('#hiddens').empty().append(fm.hiddens.hidden_objects);
            if (response.data.paths) {         
                fm.paths  = response.data.paths.loop;
                fm.parent = response.data.paths.parent;
                fm.config.work_path = response.data.paths.work_path;
            }
            else {
                fm.paths  = new Array();
                fm.parent = '';
                fm.config.work_path = '/';
            }
            /* Print out the list of files, sorting, bread crumbs, paging */
            fm.sort(response.data.files, fm.paging.sb, fm.paging.so);
            fm.breadCrumbs();
            fm.page(fm.paging, function(nh) { fm.printFiles(nh); });
            fm.showStatus();
            $('#cdform input[name="dname"]').focus();   
            if ($('#listfiles').is(':hidden') || $('.foldertab').is(':hidden')) {
                fm.commandDialog(args);
            }
            else if (!success && !$('#contentmessage').is(':hidden')) {
                fm.hideMessage();
            }
            else if (success) {
                fm.showMessage(args);
            }
            fm.htaccess(response.data.htaccess_users);
        }
        else {
            fm.showMessage(response);
        }
       fm.loading('end');
    });
}
/*
  modalConfirm show a modal confirm dialog
  args : should be a hash of all actions
  e.g. 
  object.modalConfirm({
    data : 'json data object',
    yes : function($modal) {
      Do something here..
    },
    no : function($modal) {
      blah blah..
    }
    ....
  });
*/
FileMan.prototype.modalConfirm = function(args) {
    var $modal  = $('#modal-dialog');
    var html    = '';
    var nwidth = 400;
    var nleft  = parseInt($(window).width() - nwidth) /2;
    $modal.jqm().removeClass().addClass('modal-dialog modal-dialog-form modal-confirm')
        .css('left', nleft + 'px').css('top', '30%').css('width', nwidth + 'px')
        .html(html).jqmShow().find('input[type="button"]').click(function() {
        var name = $(this).attr('name');
        if (name == 'button-yes' && typeof(args.yes) == 'function') args.yes($modal);
        else if (name == 'button-all' && typeof(args.all) == 'function') args.all($modal);
        else if (name == 'button-skip' && typeof(args.skip) == 'function') args.skip($modal);
        else if (name == 'button-no' && typeof(args.no) == 'function') args.no($modal);
        else if (name == 'button-cancel' && typeof(args.cancel) == 'function') args.cancel($modal);
    });
    var fm = this;
    $modal.find('h1 img').css('cursor', 'pointer').click(function() { 
        $('select[class="action"]').val('');
        fm.current.action = '';
        $modal.jqmHide();
    });
    $modal.find('form').ajaxForm({
        dataType: 'json',
        success : function(data) {
            fm.commandResponse(data);
        }
    });
}
/*
  printFiles method handles files listing
  nh : should be a page number
*/
FileMan.prototype.printFiles = function(nh) {
    if (typeof(nh) == 'undefined') nh = 1;
    var beg   = nh == 1 ? 0 : ((nh - 1) * this.paging.max_hits);
    var $body = $('.contentframe table[class="foldertab"]');
    $body.empty();
    $('.readme').remove();
    var count = 0;
    var array = '';
    var maps  = this.maps;
    /* Print out parent link */
    if (this.parent != '') {
        var tr = '\n' + this.readme + '
README\'s content\n' + this.readme + ''); } } /* Set an action for File Folder icons/links */ var fm = this; $('.link-folder[rel]').each(function() { var link = $(this); link.click(function() { fm.cd({ dname : link.attr('rel') }); return false; }); }); /* Set an action for File icons */ $('.icon').find('.link-file[rel]').each(function() { var link = $(this); link.click(function() { fm.printForm('preview', function (response) { if (response.success) { fm.preview(response.data.file); } else { fm.showMessage(response); } }, { f : link.attr('rel') }); return false; }); }); /* Set an action for File links */ $('.name').find('.link-file[rel]').each(function() { var link = $(this); link.click(function() { fm.loading('start'); fm.form.find('input[name="cmd-result"]').remove(); fm.printForm('edit', function(response) { if (response.success) { if (response.data.compressed == 1) { fm.actionDialog({ action : 'uncompress', json : response }); } else if (response.data.file) { fm.preview(response.data.file); } else { fm.editor('edit', link.attr('rel'), response.data.type, response.data.html); } } else { fm.showMessage(response); } fm.loading('end'); }, { f : link.attr('rel') }); return false; }); }); /* Set an action for permission links */ $('td[class="permission"]').find('a[rel]').each(function() { var link = $(this); link.click(function() { fm.parsePerm(link.attr('rel')); return false; }); }); /* Print out the sorting image */ $('.foldertab th a[rel] img').remove(); $('.foldertab th a[rel="' + this.paging.sb + '"]').append('
 + ') ');
    /* Set actions for checkboxes */
    var $foldertab = $('.foldertab');
    $foldertab.find('input[name="checkall"]').attr('checked', false);
    $foldertab.find('input[type="checkbox"]').each(function() {
        $(this).change(function() {
            if ($(this).val() == 'checkall') {
                $foldertab.find('input[type="checkbox"]').attr('checked', $(this).attr('checked') ? true : false);
            }
            else {
                var flag = true;
                var fname; var selected = 0;
                $foldertab.find('input[name="cinput"]').each(function() {
                    if ($(this).attr('checked')) {
                      selected++;
                      fname = $(this).val();
                    }
                    else {
                      flag = false;
                    }
                });
                if (selected == 1 && fm.current.action == 'chmod') fm.parsePerm(fname);
                $foldertab.find('input[name="checkall"]').attr('checked', flag);
            }
            fm.fileStats();
        });
    });
}
/*
  sort method handle sorting files
  source : should be an array
  sb : sort by column index
  so : sort order. It should be asc/desc
*/
FileMan.prototype.sort = function(source, sb, so) {
    this.paging.current_page = 1;
    if (typeof(source) == 'undefined') return;
    if (typeof(source) == 'object' || source.length > 0) {
        /* Need to seperate folders and files before sorting */
        var afolders = new Array(); var afiles = new Array();
        var maps     = this.maps;
        for (var i=0; i
');
    /* Set actions for checkboxes */
    var $foldertab = $('.foldertab');
    $foldertab.find('input[name="checkall"]').attr('checked', false);
    $foldertab.find('input[type="checkbox"]').each(function() {
        $(this).change(function() {
            if ($(this).val() == 'checkall') {
                $foldertab.find('input[type="checkbox"]').attr('checked', $(this).attr('checked') ? true : false);
            }
            else {
                var flag = true;
                var fname; var selected = 0;
                $foldertab.find('input[name="cinput"]').each(function() {
                    if ($(this).attr('checked')) {
                      selected++;
                      fname = $(this).val();
                    }
                    else {
                      flag = false;
                    }
                });
                if (selected == 1 && fm.current.action == 'chmod') fm.parsePerm(fname);
                $foldertab.find('input[name="checkall"]').attr('checked', flag);
            }
            fm.fileStats();
        });
    });
}
/*
  sort method handle sorting files
  source : should be an array
  sb : sort by column index
  so : sort order. It should be asc/desc
*/
FileMan.prototype.sort = function(source, sb, so) {
    this.paging.current_page = 1;
    if (typeof(source) == 'undefined') return;
    if (typeof(source) == 'object' || source.length > 0) {
        /* Need to seperate folders and files before sorting */
        var afolders = new Array(); var afiles = new Array();
        var maps     = this.maps;
        for (var i=0; i' + file.content + '') : ('
 + ') ');
            return false;
        });
    });
    $('#command-dialog select[name="user_action"]').change(function() { fm.userAction($(this).val()); });
    $('#command-dialog .contentframe .username a[rel]').each(function() {
        var link = $(this);
        link.click(function() {
            fm.actionForm('user_modify', { u : link.attr('rel') });
            return false;
        });
    });
}
FileMan.prototype.sortUsers = function(sb) {
    if (!sb) sb = 'username';
    var so = (!this.cdata.so || this.cdata.so == 'desc') ? 'asc' : 'desc';
    var ausers = this.cdata.users;
    var maps   = this.cdata.map;
    ausers.qsort(0, ausers.length, maps[sb], so);
    this.cdata.users = ausers;
    this.cdata.so    = so;
    this.printUsers(this.cdata.nh);
}
FileMan.prototype.printUsers = function(nh) {
    if (!nh) nh = 1;
    var ausers = this.cdata.users;
    var maps   = this.cdata.map;
    var beg   = nh == 1 ? 0 : ((nh - 1) * this.paging.max_hits);
    var body = $('#command-dialog .contentframe').find('table[class="foldertab"]');
    body.empty();
    var count = 0;
    for (var i=beg; i
');
            return false;
        });
    });
    $('#command-dialog select[name="user_action"]').change(function() { fm.userAction($(this).val()); });
    $('#command-dialog .contentframe .username a[rel]').each(function() {
        var link = $(this);
        link.click(function() {
            fm.actionForm('user_modify', { u : link.attr('rel') });
            return false;
        });
    });
}
FileMan.prototype.sortUsers = function(sb) {
    if (!sb) sb = 'username';
    var so = (!this.cdata.so || this.cdata.so == 'desc') ? 'asc' : 'desc';
    var ausers = this.cdata.users;
    var maps   = this.cdata.map;
    ausers.qsort(0, ausers.length, maps[sb], so);
    this.cdata.users = ausers;
    this.cdata.so    = so;
    this.printUsers(this.cdata.nh);
}
FileMan.prototype.printUsers = function(nh) {
    if (!nh) nh = 1;
    var ausers = this.cdata.users;
    var maps   = this.cdata.map;
    var beg   = nh == 1 ? 0 : ((nh - 1) * this.paging.max_hits);
    var body = $('#command-dialog .contentframe').find('table[class="foldertab"]');
    body.empty();
    var count = 0;
    for (var i=beg; i' + access.join("\n") + '<\/td>';      
        tr += '