dojo.require('dojo.fx');    // for chaining animations (used in the news ticker)
dojo.require('dojox.widget.Roller');
dojo.require('dojo.io.iframe');


// Subclass of the Roller widget, with customized animation settings for the
// news ticker on the cluster list.
dojo.addOnLoad(function() {
    dojo.declare("NewsTicker", dojox.widget.Roller, {
        makeAnims: function(){
            var n = this.domNode;
                dojo.mixin(this, {
                    _anim: {
                        "in": dojo.fadeIn({ node: n, duration: 500 }),
                        "out": dojo.fadeOut({ node: n, delay: 16000, duration: 1000 })
                    }
                });
            this._setupConnects();
        }
    });
});

var CC = {};

(function(){
    
    CC.serverError = [{
        "field": "",
        "message": "A server error occurred."
    }];
    // Given a formID, find all of the error tags in the form and set them
    // to have no content.
    CC.clearFormErrors = function(formId) {
        dojo.query("#" + formId + " span.error").forEach(function(node){
    	    node.innerHTML = "";
    	});	
    };
    
    // Given a formId, clear all of it's potential content:
    //   - input tags
    //   - errors
    CC.clearForm = function(formId) {
        dojo.query("#" + formId + " input").forEach(function(node) {
			node.value = "";
		});
		CC.clearFormErrors(formId);
    };
    
    // Applies a list of errors to a valid CC form, assumes the errors
    // object is of the style that is passed back from the CC API.
    CC.displayFormErrors = function(formId, errors) {
        for(var i=0; i< errors.length; i++) {
			if(errors[i]["field"]!=="") {
			    dojo.query("#" + formId + " #" + errors[i]["field"] + "_error").forEach(function(node) {
			       node.innerHTML = errors[i]["message"] + "<br/>"; 
			    });
			} else {
			    dojo.query("#" + formId + " #form_error").forEach(function(node){
			       node.innerHTML = errors[i]["message"] + "<br/>"; 
			    });
			}
		}
    };
    
})();

/* *****************************************
 * 		BROWSER DETECT SETTINGS
 ******************************************/

// Insert a browser/OS/version class on body so that
// browser CSS can be handled
function addBrowserClasses()
{
    var element = dojo.body();
    dojo.addClass(element, BrowserDetect.browser);
    dojo.addClass(element, 'v'+BrowserDetect.version);
    dojo.addClass(element, BrowserDetect.OS);
}

/* *****************************************
 * 		ERROR HANDLING/LOGGING
 ******************************************/

// Handle errors differently depending upon if we are in debug more or not
function handleError(errorMessage)
{
    if (inDebugMode)
    {
        alert(errorMessage);
    }
}


/* *****************************************
 * 				AJAX
 ******************************************/

// handle ajax get reposonse by using dojo.
// TODO: need to track any errors
function getAjaxResponse(url, dataToSend, callback)
{
    dojo.xhrGet({
       url: url,
       handleAs: 'json',
       content: dataToSend,
       load: function(data, args) { processResponse(data, args, callback); },
       error: function(data, args) { handleError(data); }
    });
}


// handle ajax post response
function postAjaxResponse(url, dataToSend, callback)
{
    dojo.xhrPost({
        url: url,
        handleAs: 'json',
        load: function(data, args) { processResponse(data, args, callback); },
        error: function(data, args) { handleError(data); },
        postData: dataToSend
    });

}

// Update the page with the new html code.
function updateDisplay(decodedData)
{
    // if the 'location' var is present then redirect to that page
    if (decodedData["location"]!=undefined)
    {
        window.location = decodedData["location"];
    }

    if (decodedData["html"]!=undefined)
    {
        var list = decodedData["html"];
        for (var n = 0; n < list.length; n++)
        {
            var element = dojo.byId(list[n][0]);
            if (element) {
                deleteWidgets(element);
                element.innerHTML = list[n][1];
            }
            dojo.parser.parse();
        }
    }
}

function processResponse(data, args, callback)
{
    updateDisplay(data);
    if(callback)
    {
        callback(data);
    }
}

/* *****************************************
 * 		   AJAX SUBMIT PROCEDURES
 ******************************************/

// submits the form with an additional "xhr" parameter
function sendForm(form, callback)
{    
     dojo.xhrPost({
         form: form,
         handleAs: 'json',
         load: function(data, args) { processResponse(data, args, callback); },
         error: function(data) { handleError(data); }
     });
}


function sendFormIframe(form, callback) {
    dojo.io.iframe.send({
        form: form,
        handleAs: 'text',
        method: 'POST',
        enctype: "multipart/form-data",
        load: function(data, args) {
            // because of the silly wrapping of JSON within a textarea required
            // by dojo.io.iframe.send we have to substitue textarea for **textarea** server
            // side which we now have to replace client side before rendering....
            while(data.indexOf("**textarea**")!==-1) {
                data = data.replace("**textarea**", "textarea");
            }
            //data = JSON.parse(data);
            data = dojo.fromJson(data);
            processResponse(data, args, callback); 
        },
        error: function(data) { handleError(data); }
    });
}
// submits the form that has the given id with an additional "xhr" parameter
function sendFormById(formId, callback)
{
    var form = dojo.byId(formId);
    sendForm(form, callback);
}

function deleteWidgets(id) {
    var widgets = dijit.findWidgets(dojo.byId(id));
    for(var i = 0; i < widgets.length; i++)
    {
       widgets[i].destroyRecursive();
    }
}

function sendFormByIdIframe(formId, callback) {
    var form = dojo.byId(formId);
    sendFormIframe(form, callback);
}

// sends data to the specified url
function getLink(url, callback)
{
    var dataToSend = { };
    getAjaxResponse(url, dataToSend, callback);
}

// sends data to the specified anchor's url
function getLinkSingleClick(anchor, callback)
{

    if (anchor.disabled !== true)
    {
        var url = anchor.href;
        var dataToSend = { xhr : '' };
        
        // disable future clicks
        anchor.href = void(0);
        anchor.disabled = true;
        
        // Save the callback for onclick so that we can disable it for the 
        // duration of the AJAX call and then bring it back when the call finishes
        var cb = anchor.onclick;
        anchor.onclick = null;
        var actualCB = null;
        if(callback) {
            actualCB = function() {
                callback();
                anchor.onclick = cb;
            };
        } else {
            actualCB = function() { anchor.onclick = cb; };
        }


        //getAjaxResponse(url, dataToSend, callback);
        getAjaxResponse(url, dataToSend, actualCB);
        //anchor.onclick = callback;

        // disable future clicks
        //anchor.href = void(0);
        //anchor.disabled = true;

    }
}

// Confirms before submitting link
function confirmThenGetLink(anchor, url, message)
{
    /* create a confirmation message */
    if (confirm(message))
    {
        if(anchor) {
            // disable future clicks
            anchor.href = void(0);
            anchor.disabled = true;
        }
        getLink(url, null);
        return true;
    }
    else
    {
        return false;
    }
}

// Submit the form with ajax header included
function submitForm()
{
    sendForm(this.form);
}


/* Used with a onkeydown or onkeypress event.  Will determine if the keypress
  is 'Enter' (keycode 13) and submit the form if it is 'Enter')
*/
function submitenter(myfield,e)
{
    var keycode;
    if (window.event) {
        keycode = window.event.keyCode;
    }
    else if (e) {
        keycode = e.which;
    }
    else {
        return true;
    }

    if (keycode == 13) {
    myfield.form.submit();
    return false;
    }
    else {
    return true;
    }
}

/* This will be used for links that post data
  Right now it is only inserts the url into the href */
function submitLinkAsForm(url)
{
    window.location.href = url;
}

// Confirm before submitting the link
function confirmThenSubmitLinkAsForm(url,message)
{
    /* create a confirmation message */
    if (confirm(message))
    {
        submitLinkAsForm(url);
        return true;
    }
    else
    {
        return false;
    }
}

/* Updates the form's action to the new url before submitting */
function updateActionSubmit(formId, anchor)
{
    var form = dojo.byId(formId);
    form.action = anchor.href;
    sendForm(form);
}

/* Updates the form's action to the new url before submitting.
 * Configured to keep user from clicking the link multiple times.
 * After the first click the link is disabled and an additional class
 * is added that allows a updating icon to be used. If the link
 * is already disabled don't do anything.*/
function updateActionSubmitSingleClick(formId,anchor)
{
    if (anchor.disabled !== true)
    {
        var form = dojo.byId(formId);
        form.action = anchor.href;
        anchor.href = void(0);
        anchor.disabled = true;
        dojo.addClass(anchor, 'working');
        //anchor.style.visibility='hidden'
        sendForm(form);
    }
}


/* *****************************************
 * 		   UPDATE POLLING
 ******************************************/

// Start polling the provided url
function startPolling(url)
{
    dojo.addOnLoad(function() { scheduleTimeout(url); } );
}

// Run the checkUpdate() script every 30 secs
function scheduleTimeout(url)
{
    // Check for updates every 30 seconds
    window.setTimeout(function() { checkUpdate(url); }, 30000);
}

// get the response and extract the new url from the decodedData
// and then schedule the next timeout.
function checkUpdate(url)
{
    function getNewUrl(decodedData)
    {
        var newUrl;
        if (decodedData["new_url"])
        {
            newUrl = decodedData["new_url"];
            scheduleTimeout(newUrl);
        }
    }
    getLink(url, getNewUrl);
}

/* *****************************************
 * 		   		TAB CONTROL
 ******************************************/

/* These are used by the tab navigation to add/remove the hover class
  for mouseover and mouseouts. */
function setHover(element)
{
    dojo.addClass(element, 'hover');

    if(dojo.hasClass(element, 'right'))
    {
        dojo.addClass(dojo.byId('right-end'), 'right-end-hover');
    }

    if(dojo.hasClass(element, 'left'))
    {
        dojo.addClass(dojo.byId('left-end'), 'left-end-hover');
    }
}

function removeHover(element)
{
    if(dojo.hasClass(element, 'hover'))
    {
        dojo.removeClass(element, 'hover');
    }

    if(dojo.hasClass(element, 'right'))
    {
        dojo.removeClass(dojo.byId('right-end'), 'right-end-hover');
    }

    if(dojo.hasClass(element, 'left'))
    {
        dojo.removeClass(dojo.byId('left-end'), 'left-end-hover');
    }
}

/* *****************************************
 *              PAGE REDIRECT
 ******************************************/

function countDown(el, timeLeft, redirectLocation) 
{ 
    if(timeLeft === 0) 
    {
        window.location.href = redirectLocation; 
    }
    else 
    {
        timeLeft--;
        scheduleRedirect(el, timeLeft,redirectLocation);
    }
    el.innerHTML = timeLeft;
}
  
function scheduleRedirect(el, timeLeft, redirectLocation) 
{
    setTimeout(function() { countDown(el, timeLeft,redirectLocation); }, 1000);
}


/* *****************************************
 * 		   DYNAMIC CHOICE FIELDS
 ******************************************/


//removes the 'selected' class from all the cluster blocks in the poolList and then
//sets the specified element as selected and displays the sidebar using the url.
function selectThisPool(poolId, url)
{
    // loop through all the poolBlocks in the poolList
    var poolList = dojo.byId("poolList");

    // get all of the immediate children elements of #poolList
    dojo.query('#poolList > *').forEach(function(node, index, array){
    dojo.removeClass(node, "selected");
    });

    // Update the id of the sidebar pane that will be replaced
    var sidebar = dojo.byId("sidebar");
    sidebar.firstChild.id = "poolDetail_id_" + poolId;

    var elementId = 'poolBlock_' + poolId;
    var element = dojo.byId(elementId);

    var pos = dojo.position(element, true);

    // we subtract 20 from the position because of margin on the list items
    dojo.style(sidebar.firstChild, {top: pos.y-20+"px", position: "absolute" });

    dojo.addClass(element, 'selected');
    getLink(url, poolDetailsCallback);

}

// This is a callback function used after we have ajax loaded the cluster details
// sidebar. This callback re-positions the sidebar if it overlaps the footer
// Note: This happens if you select one of the final items in the list.
function poolDetailsCallback() {
    var sidebar = dojo.byId("sidebar");
    var detailsPosition = dojo.position(sidebar.firstChild, true);
    var footerPosition = dojo.position("footer", true);
    if(detailsPosition.y+detailsPosition.h > footerPosition.y) {
        // get the amount of overlap
        var newPos = detailsPosition.y-(detailsPosition.y+detailsPosition.h-footerPosition.y);
        dojo.style(sidebar.firstChild, {top: newPos+"px", position: "absolute"});
    }
}

/* Creates an updated image list based upon the user-
 * selected machine type.
 */
function updateImageList(machineElement,url)
{
    var poolId = machineElement.parentNode.getAttribute('poolId');
    var machineId = machineElement.options[machineElement.selectedIndex].value;
    var newUrl = url + '/' +  machineId + '/' + poolId + '/';
    getLink(newUrl, null);
}

/* Creates an updated application list based upon the
 * user-selected pool.
 */
function updateApplicationList(poolType,url)
{
    var poolId = poolType.parentNode.getAttribute('poolId');
    var poolTypeId = poolType.options[poolType.selectedIndex].value;
    var newUrl = url + '/' + poolTypeId + '/';
    getLink(newUrl, null);
}

/* Creates an updated application list based upon the
 * user-selected pool.
 */
function updateVersionList(app,url)
{
    var appId = app.options[app.selectedIndex].value;
    var newUrl = url + '/' + appId + '/versions/';
    getLink(newUrl, null);
}




