// Javascript from Moodle modules
/**
 * This function is used to add/remove
 * the style named 'checked' to/from the
 * passed element's parent DIV.
 *
 * This function is used when checking
 * checkboxes or radio buttons.
 *
 * @param object el This element's parent will be used when adjusting the style
 * @param string parentClass Name of the parent DIV class to find
 * @param string groupClassName Name of a group of elements that should have the class 'checked' removed before toggling the passed one (el).
 * @return void
 **/
function assessToggleStyle(el, parentClass, groupClassName) {
    // Holds the parent element
    var obj;

    if (groupClassName) {
        var parent   = findParentNode(el, 'DIV', groupClassName);
        var elements = parent.getElementsByTagName('input');

        // Turn remove the style 'checked' from all elements in elements
        for (i = 0; i < elements.length; i++) {
            obj = findParentNode(elements[i], 'DIV', parentClass);

            if (obj.className.indexOf('checked') != -1) {
                obj.className = obj.className.replace(new RegExp(' ?checked'), '');
            }
        }
    }

    // Toggle the passed element
    obj = findParentNode(el, 'DIV', parentClass); 

    if (obj.className.indexOf('checked') == -1) {
        obj.className += ' checked';
    } else {
        obj.className = obj.className.replace(new RegExp(' ?checked'), '');
    }
}

/**
 * Holds the assessAutoSave object
 *
 * @var object
 **/
var assessAjaxObject = new assessAutoSave();

/**
 * Constructor - set defaults
 *
 * @return void
 **/
function assessAutoSave() {
    this.saveTimeoutId = 0;
    this.saveInProgress = false;
    this.formsToSave = Array();
    this.varsAreSet = false;
    this.saveInterval = 15000;      // Overall save interval.  Can only save every this.saveInterval miliseconds
    this.changeInterval = 10000;    // Save interval for all form elements
    this.textChangeInterval = 4000; // Save interval for textareas (overrides this.changeInterval)
    this.lastSave = 0;
}
/**
 * Variable setup routine - adds method to window.onload
 *
 * @param string wwwroot WWW root of the site
 * @param int offSet User's time minus current time (seconds)
 * @return void
 **/
assessAutoSave.prototype.setVars = function(wwwroot) {
    if (!this.varsAreSet) {
        this.wwwroot = wwwroot;

        if (typeof window.onload == "function") {
            var oldmethod = window.onload;
            window.onload = function() {
                oldmethod();
                assessAjaxObject.setListeners();
            }
        } else {
            window.onload = function() {
                assessAjaxObject.setListeners();
            }
        }
    }
    this.varsAreSet = true;
};
/**
 * Adds event listerns to form elements
 *
 * @return void
 **/
assessAutoSave.prototype.setListeners = function() {
    var forms = document.getElementsByName('assessaddformautosave');
    var other, textareas, form, datachange, datakeyup, iframs;

    for (var f = 0; f < forms.length; f++) {
        form = forms[f];
        form.assessCount = f;  // Used as a key later

        other = Array();
        textareas = Array();

        iframes = form.getElementsByTagName('iframe');
        for (i = 0; i < iframes.length; i++) {
            textareas.push(iframes[i].contentWindow.document);
        }
        for (i = 0; i < form.length; i++) {
            el = form.elements[i];
            if (el.tagName == 'TEXTAREA') {
                textareas.push(el);
            } else if (el.type != 'hidden' && el.type != 'button' && el.type != 'submit') {
                other.push(el);
            }
        }
        datachange = { formel: form, interval: this.changeInterval };
        YAHOO.util.Event.addListener(other, "click", assessAjaxObject.registerChange, datachange, assessAjaxObject);
        datakeyup = { formel: form, interval: this.textChangeInterval };
        YAHOO.util.Event.addListener(textareas, "keyup", assessAjaxObject.registerChange, datakeyup, assessAjaxObject);
    }
};
/**
 * Registers a form for saving and fires off setSaveTimeout()
 *
 * @param object e Event object
 * @param object data data.formel is the element of the form to save; data.interval is the wait till save
 * @return void
 **/
assessAutoSave.prototype.registerChange = function(e, data) {
    this.formsToSave[data.formel.assessCount] = data.formel;
    this.setSaveTimeout(data.interval);
};
/**
 * Sets a timeout for when to save the queue of forms.  Also
 * ensures that the save does not happen more frequently than
 * this saveInterval time.
 *
 * @param int milisec Miliseconds to save
 * @return void
 **/
assessAutoSave.prototype.setSaveTimeout = function(milisec) {
    var now = new Date();
    var timepassed = now.getTime() - this.lastSave;
    if (timepassed < this.saveInterval && this.lastSave != 0) {
        var timeleft = this.saveInterval - timepassed;
        if (timeleft > milisec) {
            milisec = timeleft;
        }
    }
    if (this.saveTimeoutId != 0) {
        clearTimeout(this.saveTimeoutId);
    }
    this.saveTimeoutId = setTimeout("assessAjaxObject.saveTimeoutId = 0; assessAjaxObject.saveForms();", milisec);
};
/**
 * Submits all forms that are targeted for saving
 *
 * @return void
 **/
assessAutoSave.prototype.saveForms = function() {
    if (!this.saveInProgress) {
        this.saveInProgress = true;

        if (this.formsToSave.length > 0) {
            var form, callback;

            if (typeof window.onunload == "function") {
                window.onunload();  // Moves HTMLEditor text to its textarea
            }

            for (var key in this.formsToSave) {
                form = this.formsToSave[key];

                callback = { success:this.handleSuccess,
                             failure:this.handleFailure,
                             argument:form,
                             scope:assessAjaxObject };

                YAHOO.util.Connect.setForm(form);  // Sets all form data for submitting
                YAHOO.util.Connect.asyncRequest('POST', this.wwwroot+'/mod/assess/rest.php', callback);
            }
            this.formsToSave = Array();
        }
    } else {
        // Still performing save - wait longer
        this.setSaveTimeout(this.saveInterval);
    }
};
/**
 * Handles successful asyncRequest call - sends feedback to user
 *
 * @return void
 **/
assessAutoSave.prototype.handleSuccess = function(o) {
    var divs = o.argument.getElementsByTagName('div');

    if (o.responseXML != null) {
        var root = o.responseXML.documentElement;
        var submissionid = root.getElementsByTagName('submissionid')[0].firstChild.nodeValue;
        var timesaved = root.getElementsByTagName('timesaved')[0].firstChild.nodeValue;

        // Update the time
        divs[0].getElementsByTagName('span')[0].innerHTML = timesaved;

        // Update the submissionid if not 0
        if (submissionid != 0) {
            var inputs = o.argument.getElementsByTagName('input');
            for (var i = 0; i < inputs.length; i++) {
                if (inputs[i].name == 'submissionid') {
                    inputs[i].value = submissionid;
                    break;
                }
            }
        }
        this.handleCommon(divs[1], divs[0]);
    } else {
        // No XML returned, failed
        this.handleCommon(divs[0], divs[1]);
    }
};
/**
 * Handles failed asyncRequest call - sends feedback to user
 *
 * @return void
 **/
assessAutoSave.prototype.handleFailure = function(o) {
    var divs = o.argument.getElementsByTagName('div');
    this.handleCommon(divs[0], divs[1]);
};
/**
 * Handles common asyncRequest tasks for success/failure
 *   - Display success/failure info to user
 *   - Update variables
 *
 * @return void
 **/
assessAutoSave.prototype.handleCommon = function(hide, show) {
    // Set visibility
    if (YAHOO.util.Dom.hasClass(show, 'hidden')) {
        YAHOO.util.Dom.removeClass(show, 'hidden')
    }
    if (!YAHOO.util.Dom.hasClass(hide, 'hidden')) {
        YAHOO.util.Dom.addClass(hide, 'hidden');
    }

    this.saveInProgress = false;

    var date = new Date();
    this.lastSave = date.getTime();
};/**
 * This function checks that the selected action is valid, via checking that the
 * selected action is valid and that there is at least one checked course
 * (eg: checkchecked())
 *
 * @param object    form        Document form object
 * @return boolean
 **/
function course_management_checksubmit(form) {
    var destination = form.courseaction.options[form.courseaction.selectedIndex].value;
    if (destination == "" || !course_management_checkchecked(form)) {
        form.courseaction.selectedIndex = 0;
        return false;
    } else {
        // Modifies the forms action value to submit to selected page
        return course_management_form_action(form, destination);
    }
}

/**
 * This function checks all inputs on the form that are of type checkbox to
 * ensure that at least one checkbox is selected
 *
 * @param object    form    Document form object
 * @return boolean
 **/
function course_management_checkchecked(form) {
    var inputs = document.getElementsByTagName("INPUT");
    var checked = false;
    inputs = filterByParent(inputs, function() {return form;});
    for(var i = 0; i < inputs.length; ++i) {
        if (inputs[i].type == "checkbox" && inputs[i].checked) {
            checked = true;
            // Only needs to check for one checked value
            break;
        }
    }
    return checked;
}

/**
 * This function modifies the form's action to passed destination url and
 * optionally submits.
 *
 * @param object    form        Document form object
 * @param string    destination URL of destination
 * @param boolean   submit      Submits form if set to true...returns bool otherwise
 **/
function course_management_form_action(form, destination, submit) {
    form.action = destination;
    if (submit) {
        form.submit();
    } else {
        return true;
    }
}/**
 * This function checks that the selected action is valid, via checking that the
 * selected action is valid and that there is at least one checked user
 * (eg: checkchecked())
 *
 * @param object    form        Document form object
 * @param integer   courseid    Current course id
 * @return boolean
 **/
function manage_users_checksubmit(form, id) {
    var destination = form.manageaction.options[form.manageaction.selectedIndex].value;
    if (destination == "" || !manage_users_checkchecked(form)) {
        form.manageaction.selectedIndex = 0;
        return false;
    } else {
        // Modifies the forms action value to submit to selected page
        return manage_users_form_action(form, destination);
    }
}

/**
 * This function checkes all inputs on the form that are of type checkbox to
 * ensure that at least one checkbox is selected
 *
 * @param object    form    Document form object
 * @return boolean
 **/
function manage_users_checkchecked(form) {
    var inputs = document.getElementsByTagName("INPUT");
    var checked = false;
    inputs = filterByParent(inputs, function() {return form;});
    for(var i = 0; i < inputs.length; ++i) {
        if (inputs[i].type == "checkbox" && inputs[i].checked) {
            checked = true;
            // Only needs to check for one checked value
            break;
        }
    }
    return checked;
}

/**
 * This function modifies the form's action to passed destination url and
 * optionally submits.
 *
 * @param object    form        Document form object
 * @param string    destination URL of destination
 * @param boolean   submit      Submits form if set to true...returns bool otherwise
 **/
function manage_users_form_action(form, destination, submit) {
    form.action = destination;
    if (submit) {
        form.submit();
    } else {
        return true;
    }
}

/**
 * This function checks that the dropbox has a valid course selected (not index 0)
 *
 * @param object    form  document form dropbox object
 * @return boolean
 **/
function manage_users_check_dropbox(dropbox) {
    if (dropbox.selectedIndex == 0) {
        return false;
    }
    return true;
}/**
 * This function opens a popup to the add mylink page...if blocked...sets location to the url
 *
 * @param string url Page url
 **/
function block_recent_history_js_popup(url) {
    if (!window.open(url, "add_mylink", "menubar=no,width=650,height=550,toolbar=no,resizable=yes,scrollbars=yes")) {
        window.location = url;
    }

}

// Var to pass around the linkid between functions
var brhlinkid = null;
/**
 * Function called from 'Add to MyLinks' button which adds the link to the my_links API
 *
 * @param integer courseid  id of course
 * @param integer linkid    id of link to add
 **/
function block_recent_history_add_to_my_link(courseid, linkid) {
    xmlHttp = GetXmlHttpObject();
    if (xmlHttp == null) {
        // Provide alternative to this...
        window.alert("Your browser doesn't support AJAX!...Showing/Hiding links currently disabled.");
        return;
    }
    // Calls the php script to validate/process the request
    brhlinkid = linkid;
    var url = 'add_link_ajax.php?courseid='+courseid+'&linkid='+linkid;
    xmlHttp.onreadystatechange = block_recent_history_change_add_button;
    xmlHttp.open("GET", url, true);
    xmlHttp.send(null);
}

/**
 * Function called from AJAX onreadystatechange event to process response from ajax request,
 * On success, will de-activate 'Add to MyLinks' button and change the name
 *
 **/
function block_recent_history_change_add_button() {
    if (xmlHttp.readyState == 4) {
        // No action if result failed (database not changed)
        if (xmlHttp.responseText != '') {
            // Dont actually need response text
            retval = xmlHttp.responseText;
            // Updates the title property
            updateLink = document.getElementById('addlink'+brhlinkid);
            updateLink.onclick = '';
            updateLink.innerHTML = retval;
        }
    }
}
    
// Creates an XHR Object
function GetXmlHttpObject() {
    var xmlHttp = null;
    try {
        // Firefox, Opera, Safari
        xmlHttp = new XMLHttpRequest();
    } catch (e) {
        // IE
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            xmlHttp = new ActiveXObject("Microsoft.HMLHTTP");
        }
    }
    return xmlHttp;
}

/**
 * Function checks if DOM is ready before printing history list
 * since IE crashes horribly if it is not
 * (YUI 2.3.1 has this function built in...)
 * (Currently not used)
 *
function onDOMReady() {
    if (document.all && !window.opera){ //Crude test for IE
    //Define a "blank" external JavaScript tag
      document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="//:"></script>')
      var contentloadtag=document.getElementById("contentloadtag")
      contentloadtag.onreadystatechange=function(){
        if (this.readyState=="complete")
          brhMenu.render("block_recent_history_menu");
      }
    } else {
        brhMenu.render("block_recent_history_menu");
    }
}
 **/
 
/**
 * Old YUI version of testing readiness of DOM (for IE)
 * Creates an object that checks when passed element is ready, then calls
 * function block_recent_history_ready with object as a param
 **/
function TestObj(id, functioncall) {
    YAHOO.util.Event.onContentReady(id, eval(functioncall), this);
}/**
 * Function displays show/hide button based on presence of cookie.
 *
 **/
function blockTeacherNotesToggleText(elId, showtxt, hidetxt, uid) {
    var cook = new cookie('hide:inst'+elId+':uid'+uid).read();
    var obj = document.getElementById('tnShowHide'+elId);
    if(cook == null) {
        obj.innerHTML = hidetxt;
    } else {
        obj.innerHTML = showtxt;
    }
}

/**
 * Checks if both show and hide cookies a set.  If 
 * both are not set, then the hide cookie is set.
 *
 **/
function blockTeacherNotesDefaultHide(id, uid) {
    var obj  = document.getElementById(id);
    var hidecook = new cookie('hide:' + id + ':uid'+uid).read();
    var showcook = new cookie('show:' + id + ':uid'+uid).read();
    if(hidecook == null && showcook == null) {
        new cookie('hide:' + obj.id + ':uid'+uid, 1, 356, '/').set();
    }
}

/**
 * This is a elementToggleHide() wrapper.  It also manages
 * a show cookie based on the blocks visiblity.
 *
 **/
function blockTeacherNotesToggleHide(el, persistent, elementFinder, uid) {
    if(!elementFinder) {
        var obj = el;
    } else {
        var obj = elementFinder(el);
    }
    if(obj.className.indexOf('hidden') == -1) {
        // Create hide cookie
        new cookie('hide:'+obj.id+':uid'+uid,1,356, '/').set();
        // Destroy show cookie
        new cookie('show:' + obj.id + ':uid'+uid, 1, -1, '/').set();
    } else {
        // Create show cookie
        new cookie('show:' + obj.id + ':uid'+uid, 1, 356, '/').set();
        // Destroy hide cookie
        new cookie('hide:' + obj.id + ':uid' + uid, 1, -1, '/').set();
    }
    blockTeacherNotesElementToggleHide(el, persistent, elementFinder);
}
/**
 * Modified from /lib/javascript-static.js to prevent creation of cookie
 * without the user id
 */
function blockTeacherNotesElementToggleHide(el, persistent, elementFinder) {
    if(!elementFinder) {
        var obj = el;
    }
    else {
        var obj = elementFinder(el);
    }
    if(obj.className.indexOf('hidden') == -1) {
        obj.className += ' hidden';
        var shown = 0;
    }
    else {
        obj.className = obj.className.replace(new RegExp(' ?hidden'), '')
        var shown = 1;
    }
}

/**
 * Modified from /lib/javascript-static.js to read from customised show/hide cookie
 **/
function blockTeacherNotesElementCookieHide(id, uid) {
    var obj  = document.getElementById(id);
    var cook = new cookie('hide:' + id + ':uid'+uid).read();
    if(cook != null) {
        blockTeacherNotesElementToggleHide(obj, false);
    }
}/**
 * If no topic is set, alert them.
 */
function blockTeoChatroomCheckSubmit(ta, msg) {
    if(ta.value=='') {
        if(msg!='') {
           alert(msg);
        }
        return false;
    }
    return true;
}

/**
 * Set time out for this page to be reoaded after this method
 * is called. (when submitting new topic)
 */
function blockTeoChatroomCheckSubmitRefresh(ta, w, seconds) {
    if(blockTeoChatroomCheckSubmit(ta, '')) {
        setTimeout(function() { w.location.reload(); }, seconds);
    }
}

/**
 * Set time out for this page to be reoaded after this method
 * is called. (When entering chat)
 */
function blockTeoChatroomCheckEnterRefresh(seconds) {
    setTimeout(function() { window.location.reload(); }, seconds);
}

/**
 * Unused function.
 *
 * Could be used with setInterval to allow nice
 * checking of topicString's contents. BTW firfox
 * does not render disabled buttons properly
 * using the TEO theme.
 */
function blockTeoChatroomCheckInput(ta, b) {
    if(ta.value!='') {
        b.disabled = false;
    } else {
        b.disabled = true;
    }
}