//****************************************************************************
// LOGIN
//****************************************************************************

function doLogout(form /* HTMLFormElement */) {
    RPC.API.logout(function() { window.location.pathname = ctxpath+"/login.xsp"; });
}

function readLoginInfo() {
    var lf = $("login-form"), lc = getCookie("login-cookie");
    if (lf == null || lc == null) return;
    lc = lc.split(" ");
    lf.domain.value = lc[0];
    lf.userid.value = lc[1];
}

function writeLoginInfo() {
    var lf = $("login-form");
    if (lf == null) return;
    var lc = lf.domain.value.trim()+" "+lf.userid.value.trim();
    putCookie("login-cookie", lc, 365);
}


//****************************************************************************
//INIT DATA
//****************************************************************************

function initSchema() {
    RPC.API.initSchema(function(ok) { if (ok) $("statusbar").note("Initial schema has been created."); });
}

function initData() {
    RPC.API.initData(function(ok) { if (ok) $("statusbar").note("Initial data has been created."); });
}


//****************************************************************************
// BASIC TOOLBAR ACTIONS
//****************************************************************************

function setView(view, id) { _setView(view, id); }

function _setView(view, id, params) {
    var currentView = getParameter("view", "grid");
    var grid = $("grid"), pqs = "";
    if (id == null && grid != null && grid.hasSelection()) id = grid.getSelectedItem().data.id;
    if (id == null) id = getParameter("id", -1);
    if (params != null) for (var prop in params) pqs += ("&"+prop+"="+escape(params[prop]));
    window.location.search = "?view="+view+"&id="+id+pqs;
}

function gridAdd() { setView("form", -1); }

function gridRemove() {
    var grid = $("grid");
    if (!grid.hasSelection()) return;
    var id = grid.getSelectedItem().data.id;
    var type = grid.getAttribute(ATTRS.DATATYPE);
    if (!confirm("Are you sure you want to remove it?  The is no turning back!")) return;
    RPC.API.remove(type, id, function(obj) {
        if (obj.id = id) {
            $("statusbar").note("Removed!");
            refresh();
        }
    });
}

function gridView() {
    var grid = $("grid");
    if (!grid.hasSelection()) {$('statusbar').error('Select an item first'); return;}
    if (grid.params) _setView("form", $(grid).getSelectedItem().data.id, grid.params);
    else setView("form", $(grid).getSelectedItem().data.id);
}

function formAdd() { setView("form", -1); }

function formRemove() {
    var form = $("form");
    if (form == null) return;
    var id = form.data.id;
    var type = form.getAttribute(ATTRS.DATATYPE);
    if (!confirm("Are you sure you want to remove it?  The is no turning back!")) return;
    RPC.API.remove(type, id, function(obj) {
        if (obj.id = id) setView("grid");
    });
}

function formEdit() {
    form = $("form");
    form.setEnabled(true, true);
    state();
}

function _save(form, add /*boolean*/) {
    if (form == null) form = $("form");
    var type = form.getAttribute(ATTRS.DATATYPE);
    var obj = form.getValues({ __type__: type });
    if (_curProjId != -1) obj.project = _curProjId;
    // console.log("obj: "+JSON.encode(obj));
    RPC.API.put(obj, function(savedObj) {
        $("statusbar").note("Saved!");
        form.id.setValue(savedObj.id);
        form.setEnabled(false);
        if (form == $("form")) state();
        if (add == true) formAdd();
    });
}

function save(form) {
    _save(form, false);
}

function saveAdd(form) {
    _save(form, true);
}

function cancel() {
    form = $("form");
    var id = form.id.getValue();
    if (id == null || id.length == 0 || id == -1) setView("grid");
    else {
        form.setEnabled(false);
        state();
    }
}

function right() { $("grid").next(); }

function left() { $("grid").prev(); }

function state() {
    var view = getParameter("view", "grid");
    if (view == "grid") gridState();
    if (view == "form") formState();
}

function gridSelectEnabledExpressions(){
    // this method will be called whenever the user makes a selection in a grid
}

function gridEnabledExpressions() {
    var grid = $("grid");
    /*
    Widget.setEnabledExpr($("view-form"),   function() { return grid.hasSelection(); });
    Widget.setEnabledExpr($("edit"),        function() { return grid.hasSelection(); });
    Widget.setEnabledExpr($("remove"),      function() { return grid.hasSelection(); });
    Widget.setEnabledExpr($("farleft"),     function() { return grid._cursor > 0; });
    Widget.setEnabledExpr($("left"),        function() { return grid._cursor > 0; });
    Widget.setEnabledExpr($("farright"),    function() { return grid.itemCount() == grid._limit; });
    Widget.setEnabledExpr($("right"),       function() { return grid.itemCount() == grid._limit; });
    */
    Widget.setComputedAttr($("view-form"),      "disabled", function() { return !grid.hasSelection(); });
    Widget.setComputedAttr($("edit"),           "disabled", function() { return !grid.hasSelection(); });
    Widget.setComputedAttr($("remove"),         "disabled", function() { return !grid.hasSelection(); });
    Widget.setComputedAttr($("gridEnabled"),    "disabled", function() { return !grid.hasSelection(); });
    Widget.setComputedAttr($("gridWebEnabled"), "disabled", function() { return !grid.hasSelection(); });
    Widget.setComputedAttr($("farleft"),        "disabled", function() { return grid._cursor == 0; });
    Widget.setComputedAttr($("left"),           "disabled", function() { return grid._cursor == 0; });
    Widget.setComputedAttr($("farright"),       "disabled", function() { return grid.itemCount() != grid._limit; });
    Widget.setComputedAttr($("right"),          "disabled", function() { return grid.itemCount() != grid._limit; });
}

// function gridState() { Widget.enabledState(); }
function gridState() { Widget._computeAttrs(null, "disabled"); }

/*
function gridState() {
    var grid = $("grid");
    if (grid == null) return;
    var fn = function(bn, val) { bn = $(bn); if (bn != null) bn.disabled = !val; };
    var gridMaxLeft = (grid._cursor <= 0);
    var gridMaxRight = (grid.itemCount() <= grid._max);
    fn("edit",      grid.hasSelection());
    fn("remove",    grid.hasSelection());
    fn("farleft",   !gridMaxLeft);
    fn("left",      !gridMaxLeft);
    fn("right",     !gridMaxRight);
    fn("farright",  !gridMaxRight);
}
*/

function formState() {
    var form = $("form");
    if (form == null) return;
    var fn = function(bn, val) { bn = $(bn); if (bn != null) bn.disabled = !val; };
    var formDisabled = (form != null && form.hasAttribute(ATTRS.DISABLED));
    fn("add",       formDisabled);
    fn("edit",      formDisabled);
    fn("remove",    formDisabled);
    fn("save",      !formDisabled);
    fn("saveAdd",   !formDisabled);
    fn("cancel",    !formDisabled);
}


//****************************************************************************
// EXTENDED TOOLBAR ACTIONS
//****************************************************************************

function exportProject() {
    RPC.API.exportProject(_curProjId, function() {
        $("statusbar").note("Project exported");
    });
}

function refresh() {
    // window.location.search = setParameter("refresh", "refresh");
    // window.location.reload();
    setParameter("refresh", "refresh");
    window.location.search = getQuery();
}

function loadGridData(grid /*HTMLTableElement */, filter /* Function */) {
    grid.loadData(RPC.API.getAllWithWrapper, filter); 
    state();
}

function dataStrings(type /* String */) {
    // console.log("type: "+type);
    
    // Ensure type
    if (type == null) {
        var dataObj = $("grid") || $("form");
        if (dataObj != null) type = dataObj.getAttribute(ATTRS.DATATYPE);
    }
    
    // Open dialog
    if (type != null) {
        console.log(ctxpath);
        var dialog = Dialog.load(ctxpath+"/dialogs/data-strings.xsp?type="+type, "data-strings-dialog");
        dialog.open();
    }
    else $("statusbar").warn("Could not find data!");
}

function uiStrings(type /* String */) {
}

function tooltipStrings() {
    var dialog = Dialog.load(ctxpath+"/dialogs/tooltip-strings.xsp?docName=app/project", "tooltip-strings-dialog");
    dialog.open();
}

function _saveProject(form, add) {
    if (form == null) form = $("form");
    var type = form.getAttribute(ATTRS.DATATYPE);
    var obj = form.getValues({ __type__: type });
    RPC.API.putProject(obj, function(savedObj) {
        $("statusbar").note("Saved!");
        form.id.setValue(savedObj.id);
        form.setEnabled(false);
        if (form == $("form")) state();
        if (add == true) formAdd();
    });
}

function saveProject(form) {
    _saveProject(form, false);
}

function saveAddProject(form) {
    _saveProject(form, true);
}

function gridRemoveProject() {
    var grid = $("grid");
    if (!grid.hasSelection()) return;
    var id = grid.getSelectedItem().data.id;
//    var type = grid.getAttribute(ATTRS.DATATYPE);
    if (!confirm("Are you sure you want to remove it?  The is no turning back!")) return;
    RPC.API.removeProject(id, function(obj) {
        if (obj.id = id) {
            $("statusbar").note("Removed!");
            refresh();
        }
    });
}

function formRemoveProject() {
    var form = $("form");
    if (form == null) return;
    var id = form.data.id;
//    var type = form.getAttribute(ATTRS.DATATYPE);
    if (!confirm("Are you sure you want to remove it?  The is no turning back!")) return;
    RPC.API.removeProject(id, function(obj) {
        if (obj.id = id) setView("grid");
    });
}

//****************************************************************************
// HANDLER(S)
//****************************************************************************

// What to do with grids and forms
Event.addListener(window, EVENTS.LOAD, function() { 
    // console.log("APP - Executing App event on ONLOAD");
    
    // Grid screens
    var grid = $("grid");
    if (grid != null) {
        Event.addListener(grid, EVENTS.RESPONSE, function() { state(); });
        Event.addListener(grid, EVENTS.INSPECT, function() { gridView(); });
        Event.addListener(grid, EVENTS.SELECT, function() { state(); gridSelectEnabledExpressions(); });
        Event.addListener(grid, EVENTS.FILTER, function(ev) {
            var th = ev.causeEvent.target;
            setColumnFilter(th);
        });
        gridEnabledExpressions();
    }
    
    // Form screens
    var form = $("form");
    if (form != null) {
        Event.addListener(form, EVENTS.RESPONSE, function() { state(); });
        if (getParameter("id") == -1) form.setEnabled(true, true);
    }

    // RPC error handling
    Event.addListener(RPC, EVENTS.ERROR, function() { 
        $("statusbar").error(RPC._error);
    });

}, false);


//****************************************************************************
// MISCELLANEOUS
//****************************************************************************

function setDomain(id) {
    // console.log("id: "+id);
    RPC.API.setDomain(id, function(dmn) { window.location = ctxpath+"/"; });
}

function projectSelection(ev) {
    if (ev != null) {
        var button = $(ev.currentTarget);
        if (button.onArrow(ev)) return;
    }
    
    // Open dialog
    var dialog = Dialog.load(ctxpath+"/dialogs/project-selection.xsp", "project-selection-dialog");
    dialog.open(null, function(projId) {
        if (projId == null) return;
        setProject(projId);
    });
}

function projectTutorial(projName, projTemplate, exists) {
    if (exists) {
        $("statusbar").warning("Tutorial project '"+projName+"' already created!");
        return;
    }
    
    RPC.API.createTutorialProject(projName, projTemplate, function(proj) {
        setView("form", proj.id);
    });
}

function setProject(id) {
    // console.log("id: "+id);
    RPC.API.setProject(id, function(proj) {
        window.location = ctxpath+"/";
        // if (proj != null) window.location = ctxpath+"/";
        // $("statusbar").note("Project succesfully set");
        // $("banner-project").setValue(proj == null? "" : proj.name);
    });
}

function changePassword() {
    // Open dialog
    var dialog = Dialog.load(ctxpath+"/dialogs/password-change.xsp", "password-change-dialog");
    dialog.open(null, function(oldPass, newPass) {
        if (oldPass == null || newPass == null) return;
        RPC.API.changePassword(oldPass, newPass, function(success) {
            if (success) $("statusbar").note("Password succesfully changed");
            else $("statusbar").warn("Could not change password");
        });
    });
}

function changeUserPassword(userid, newPass) {
    if (userid == null || newPass == null || userid == "" || newPass == ""){
    	$("statusbar").warn("Could not change password");
    	return;
    }
    
    RPC.API.changeUserPassword(userid, newPass, function(success) {
        if (success) $("statusbar").note("Password succesfully changed");
        else $("statusbar").warn("Could not change password");
    });
}

function exportProject() {
    // Open dialog
    var dialog = Dialog.load(ctxpath+"/dialogs/project-export.xsp", "project-export-dialog");
    dialog.open();
}

function startProjectExport() {
    var projId = $('project-selection').getValue();
    if (projId == null || projId < 0) return;
    $("close").disabled = true;
    $("startStop").innerText = "Stop";
    $("startStop").onclick = stopProjectExport;
    RPC.API.startProjectExport(projId, function(url) {
        $("statusbar").note("URL: "+url);
    });
}

function stopProjectExport() {
    RPC.API.stopProjectExport(function(url) {
        $("close").disabled = false;
        $("startStop").innerText = "Start";
        $("startStop").onclick = startProjectExport;
    });
}

function setColumnFilter(th) {
	var grid = $(grid) || $("grid");
    var name = th.getAttribute(ATTRS.NAME);
    var currFilter = grid.getAttribute(ATTRS.DATAFILTER);
    
    // Open dialog
    var dialog = Dialog.load(ctxpath+"/dialogs/column-filter.xsp", "column-filter-dialog");
    dialog.open(null, function(value) {
    	// User did not select a value on which to filter, normalize variable
        if (value == null || isEmpty(value.trim())) value = null;
        
        // No filters are being applied at the moment, normalize variable
        if (currFilter == null || isEmpty(currFilter.trim())) currFilter = null;
        
        // Build new filter with the name of this column and selected value from dialog
        var filter = (value == null? null : name+"='"+value+"'");
        
        // if filter is already being applied at this column over the same value: nothing to do
        if (th.getAttribute(ATTRS.FILTER) == filter) return;
        
        // save selected filter on column attribute
        th.setAttribute(ATTRS.FILTER, filter);
        
        // Bugfix: append filter to grid
        // var newFilter = currFilter == null ? filter : currFilter + " AND " + filter;
        // grid.setAttribute(ATTRS.DATAFILTER, newFilter);
        grid.loadData();
        // grid.setFilter(name, value);
    });
    
    // Fill dialog
    var type = grid.getAttribute(ATTRS.DATATYPE);
    var where = grid.getFilter();
    RPC.API.getValues(type, name, where, function(values) {
        var cf = $("column-filter");
        values = values.filter(function(obj) { return !isEmpty(obj); }).sort();
        cf.setOptions(values);
        cf.insertOption({ id: " ", name: "None" }, 0).style.color = "grey";
    });
}

function removeAllFilters(th) {
    var grid = $(grid) || $("grid");
    var ths = grid.tHead.rows[0].cells;
    for (var i = 0; i < ths.length; i++) ths[i].removeAttribute(ATTRS.FILTER);
    grid.removeAllFilters();
}

function saveDataStrings(prefix, grid /* HTMLTableElement */) {
    // Collect entries in a hash table
    var obj = new Object();
    var rows = grid.tBodies[0].rows;
    for (var i = 0, l = rows.length; i < l; i++) obj[rows[i].cells[0].innerText] = rows[i].cells[1].innerText;
    
    // Commit
    RPC.API.saveDataStrings(prefix, obj, "EN", function() {
        $("statusbar").note("Saved!");
        $('data-strings-dialog').close(null);        
    });    
}

function saveUIStrings(grid /* HTMLTableElement */, type /* String */) {
    // Collect entries in a hash table
    var obj = new Object();
    var rows = grid.tBodies[0].rows;
    for (var i = 0, l = rows.length; i < l; i++) {
        obj[rows[i].cells[0].innerText] = rows[i].cells[1].innerText;
    }
    
    // Commit
    RPC.API.saveUIStrings(obj, "EN", function() {
        $("statusbar").note("Saved!");
        $("ui-strings-dialog").close(null);
    });
}


//****************************************************************************
// HELPER(S)
//****************************************************************************

function getCurrentObject() {
    var grid = $("grid");
    if (grid != null && grid.hasSelection()) return grid.getSelectedItem().data;
    var form = $("form");
    if (form != null) return form.data;
    return null;
}

function getSimpleName(obj) {
    var type = obj.__type__;
    return typeof(type) == UNDEFINED? null : type.substring(type.lastIndexOf('.')+1);
}

function displayMessage(msg, html) {
    var dialog = Dialog.load(ctxpath+"/dialogs/message-display.xsp", "message-display-dialog");
    var mdd = $("message-display-div");
    if (html) mdd.innerHTML = msg;
    else mdd.innerText = msg;
    // console.log($("message-display-div"));
    dialog.open();
}

function displayXml(xml /* String */) {
    // If 'xml' is a node, serialize it
    if (xml.nodeType != null) xml = (new XMLSerializer()).serializeToString(xml);

    // Open dialog and display
    var dialog = Dialog.load(ctxpath+"/dialogs/xml-display.xsp", "xml-display-dialog", true);
    var xdp = $("xml-display-pre");
    xdp.innerText = xml;
    // DlHighlight.HELPERS.highlightByName("code", "pre");
    dialog.open();
}


function displayImage(img, file) {
    if (!file.type.match(/image.*/)) return;
    img.file = file;  
    var reader = new FileReader();  
    reader.onloadend = function(ev) { img.src = ev.target.result; };
    reader.readAsDataURL(file);
}

window.addEventListener(EVENTS.LOAD, function(){
	setInactivityTimeout();
}, false);

function redirectLogin(){
    RPC.API.isSessionAlive(function(ok){
        if( !ok ){ window.location = ctxpath+"/"; }
    });
}

function setInactivityTimeout(){
    var timeout = 900000;
    timer = setInterval(redirectLogin, timeout);
}

//****************************************************************************
// TEMPORARY
//****************************************************************************

/*
window.addEventListener(EVENTS.LOAD, function() {
    if (!location.pathname.endsWith("project.xsp")) return;
    $("grid").addEventListener(EVENTS.RESPONSE, _colorCells, false);
}, false);

function _colorCells() {
    // var template = getParameter("template", null);
    // if (template == null) return;
    var grid = $("grid");
    if (grid == null) return;
    var rows = grid.tBodies[0].rows;
    var cs = grid.getColumns();
    for (var i = 0; i < rows.length; i++) {
        var cells = rows[i].cells;
        for (var j = 0; j < cells.length; j++) {
            if (cs[j].name == "id") continue;
            var value = cells[j].innerText;
            if (!value.isNumeric()) continue;
            value = parseInt(value);
            if (value == 0) cells[j].style.backgroundColor = "#FFBBBB";
            if (value == 1) cells[j].style.backgroundColor = "#A9C5EB";
        }
    }
}
*/

//****************************************************************************
// SAVE USER METHODS
//****************************************************************************

//function _saveUser (form,add /*boolean*/) {
//    if (form == null) form = $("form");
//    var type = form.getAttribute(ATTRS.DATATYPE);
//    var obj = form.getValues({ __type__: type });
//    if (_curProjId != -1) obj.project = _curProjId;
//    // console.log("obj: "+JSON.encode(obj));
//    RPC.API.putUser(obj, function(savedObj) {
//        $("statusbar").note("Saved!");
//        form.id.setValue(savedObj.id);
//        form.setEnabled(false);
//        if (form == $("form")) state();
//        if (add == true) formAdd();
//    });
//}
//
//function saveUser(form) {
//    _saveUser(form, false);
//}
//
//function saveAddUser(form) {
//    _saveUser(form, true);
//}

//****************************************************************************
//REMOVE GROUP METHOD
//****************************************************************************

function gridRemoveGroup() {
    var grid = $("grid");
    if (!grid.hasSelection()) return;
    var id = grid.getSelectedItem().data.id;
    var type = grid.getAttribute(ATTRS.DATATYPE);
    if (!confirm("Are you sure you want to remove it?  The is no turning back!")) return;
    RPC.API.removeGroup(type, id, function(obj) {
        if (obj.id = id) {
            $("statusbar").note("Removed!");
            refresh();
        }
    });
}

