
//dojo.require("dojo.event.*");
//dojo.require("dojo.json");

/* so we can use tooltips */
//dojo.require("dojo.widget.Tooltip")

dojo.require('dojo.fx');    // for chaining animations (used in the news ticker)
dojo.require('dojox.widget.Roller');

/* *****************************************
 * 			GEN. CLASS ROUTINES
 ******************************************/

//returns true if the given class appears in element's class attribute.
//Matches the word as a separate class, so it does not match subwords: 
//testing for 'hover' will not match 'hover-state'

// These functions have been removed because they are part of Dojo core
/*function hasClass(element, className)
{
	var regexp = new RegExp("\\b" + className + "\\b");
	return regexp.test(element.className);
}

//Adds the class if it exists
function addClass(element, className)
{
	if (hasClass(element, className) === false)
	{
		element.className = (element.className + " " + className);
	}
}

//removes the class if it exists
function removeClass(element, className)
{
	setClass(element, element.className.replace(new RegExp("\\b" + className + "\\b"), ""));
}*/

//adds the class element if enabled is true, removes it if false
// NOTE: unused?
/*function setConditionalClass(element, className, enabled)
{
	if (enabled)
	{
		//addClass(element, className);
		dojo.addClass(element, className);
	}
	else
	{
	    dojo.removeClass(element, className);
		//removeClass(element, className);
	}
}*/

//removes the oldClassname if it exists, and adds newClassname
// Note: unused?
/*function switchStyle(element, oldClassname, newClassname)
{
	dojo.removeClass(element, oldClassname);
	dojo.addClass(element, newClassname);
}*/

/* Sets the element to have the given class name,
but only if it is different than what is there (which can be more efficient).
 */
 // Note: unused?
/*function setClass(element, newClass)
{
	// as an optimization, don't change the class (which forces an update)
	// unless it's really changed
	if (element.className != newClass)
	{
		element.className = (newClass);
	}
}*/


/* *****************************************
 * 		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);
    }
    else
    {
        // Do nothing.  Enventually we can send an email or something.
    }
}


/* *****************************************
 * 				AJAX
 ******************************************/

// handle ajax get reposonse by using dojo.
// TODO: need to track any errors
function getAjaxResponse(url, dataToSend, callback)
{

    //dojo.io.bind({
    //            load: function(type, data, evt, temp) { processResponse(type, data, evt, temp, callback); },
    //            error: function(type, data, evt){ }, //alert("Server Error!  An error occurred: " + data); },
    //            timeoutSeconds: 4,
    //            timeout: function(type, data, evt){ }, //alert("Timed out waiting for the server.  Try again or contact support."); },
    ///            method: 'get',
    //            url: url,
    //            content: dataToSend
    //            });
    
    dojo.xhrGet({
       url: url,
       handleAs: 'json',
       load: function(data, args) { processResponse(data, args, callback); },
       error: function(data, args) { handleError(data); }
    });
}


// handle ajax post response
function postAjaxResponse(url, dataToSend, callback)
{

    //dojo.io.bind({
    //            load: function(type, data, evt, temp) { processResponse(type, data, evt, temp, callback); },
    //            error: function(type, data, evt){ }, //alert("Server Error!  An error occurred: " + data); },
    //            timeoutSeconds: 4,
    //            timeout: function(type, data, evt){ },//alert("Timed out waiting for the server.  Try again or contact support."); },
    //            method: 'post',
    //            url: url,
    //            content: dataToSend
    //            });
    
    alert(url);
    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)
            	element.innerHTML = list[n][1];
            // TODO: I don't think these should be errors.  We really should just log them.
            //		Currently we expect to pass data back that might not have an id on the page.
            //		In that case the expected behaviour is to just do nothing with it.
            //		Eventually we'll log these to a file.
            //else
            	//handleError("Could not find " + list[n][0]);
        }
    }
}

function processResponse(data, args, callback)
{
    updateDisplay(data);
    if(callback)
    {
        callback(data);
    }
}


// process the ajax response by updating the display and running any
// additional callbacks.
// The placeholder variable just allows space for dojo to insert it's additional variable
// NOTE: deprecated for above
/*function processResponseOld(type, data, evt, placeholder, callback)
{
    if (type == 'error')
    {
        handleError('Error when retrieving data from the server!');
    }
    else
    {
        // decode the simpleJson answer from django ''details'' method.
        var decodedData = dojo.json.evalJson(data);
        updateDisplay(decodedData);
        // if there is an additional callback function run that
        if (callback)
        {
            callback(decodedData);
        }
    }
}*/

// On load add the ajax submit onclick to the send form button
// NOTE: unused
/*function addAjaxSubmit(submitButtonId)
{
    dojo.addOnLoad(function() { _addAjaxSubmit(submitButtonId); } );
}*/

// NOTE: Unused
/*function _addAjaxSubmit(submitButtonId)
{
    var sendFormButton = dojo.byId(submitButtonId);
    if (sendFormButton)
    {
        var form = sendFormButton.form;
        form.onsubmit = function() { return false; };
        //dojo.event.connect(sendFormButton, 'onclick', function() { sendForm(form); });
        dojo.connect(sendFormButton, 'onclick', function() { sendForm(form); });
    }
}*/

// Add the ajax function to the submit form using onclick.
// NOTE: Unused
/*function addAjaxOnclickSubmit(formId,type)
{
    var form = dojo.byId(formId);
    
    for (var n = 0; n < form.elements.length; n++)
    {
        // is this an element of 'type'?
        if (form.elements[n].type == type)
        {
            // submit when clicked
            form.elements[n]["onclick"] = submitForm;
        }
    }
}*/


/* *****************************************
 * 		   AJAX SUBMIT PROCEDURES
 ******************************************/

// submits the form with an additional "xhr" parameter
function sendForm(form)
{
    // check if form is a string.  If it is assume that it is an ID
    // var form = dojo.byId(form);
    
    //alert(form);
    //alert(form.action);
    //dojo.io.bind({
    //            handler: processResponse,
    //            formNode: form,
    //            content: {xhr:''}
    // });
     dojo.xhrPost({
         form: form,
         handleAs: 'json',
         load: function(data, args) { processResponse(data, args); },
         error: function(data) { handleError(data); }
     }); 
}

// submits the form that has the given id with an additional "xhr" parameter
function sendFormById(formId)
{
    var form = dojo.byId(formId);
    sendForm(form);
}


// sends data to the specified url, inserts the 'xhr' parameter
// NOTE: Unused
/*function sendData(data,url)
{
    var dataToSend = { xhr : '' };
    for (var d in data)
    {
        dataToSend[d] = data[d];
    }
    
    postAjaxResponse(url,dataToSend,callback)
}*/

// sends data to the specified url
function getLink(url, callback)
{
    var dataToSend = { xhr : '' };
    
    getAjaxResponse(url, dataToSend, callback);
}

// sends data to the specified anchor's url
function getLinkSingleClick(anchor, callback)
{

	if (anchor.disabled != true)
	{
		url = anchor.href
	    var dataToSend = { xhr : '' };
	    
	    getAjaxResponse(url, dataToSend, callback);

	    // disable future clicks
	    anchor.href = void(0);
	    anchor.disabled = true;

	}
}

// Confirms before submitting link
function confirmThenGetLink(url,message)
{
    /* create a confirmation message */
    if (confirm(message))
    {
        getLink(url, null)
        return true
    }
    else
    {
        return false
    }
}

// Confirms before submitting form
// NOTE: Unused
/*function confirmThenSubmitForm(form,message)
{
    if (confirm(message))
    {
        form.submit()
        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)
    {
        if (decodedData["new_url"])
        {
            newUrl = decodedData["new_url"];
        }
        scheduleTimeout(newUrl);
    }
    getLink(url, getNewUrl);
}

/* *****************************************
 * 		   		TAB CONTROL
 ******************************************/

/* Closure method
 [12:03:53 PM] dougbclayton says:
function mouseover(elementId)
{
    window.setTimeout(function unnamed() { hide(elementId) }, 1000);
}


function hide(id)
{
 //hide id
}
*/

/* Use to show/hide control tabs */
//var Tab = {
//    timeout : null,
//    showTab : function(elementId)
//    {
//        var element = dojo.byId(elementId)
//        clearTimeout(this.timeout);
//        if(element.style.display == 'none'){
//            /*this.timeout = setTimeout(function(){new Effect.BlindDown(e, {duration:.3, fps:40})},200);*/
//            this.timeout = setTimeout(function(){element.style.display = "block";},0);
//        }
//    },
//    hideTab : function(elementId)
//    {
//        var element = dojo.byId(elementId)
//        if(element.style.display == 'none'){
//            clearTimeout(this.timeout);
//        }else{
//            /*this.timeout = setTimeout(function(){new Effect.BlindUp(e, {duration:.3, fps:40})},300);*/
//            this.timeout = setTimeout(function(){element.style.display = "none";},0);
//        }
//    }    
//}


// Deprecated on 1/11/2010
/*var Tab = {
    showTab : function(elementId)
    {
        var element = dojo.byId(elementId)
        element.style.display = "block";
    },
    hideTab : function(elementId)
    {
        var element = dojo.byId(elementId)
        element.style.display = "none";
    }    
}*/

/* Setup so we can use dojo tooltips */



/* 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');
    }   
}



/* *****************************************
 * 		   DYNAMIC CHOICE FIELDS
 ******************************************/


//removes the 'selected' class from all the pool 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");
	/*var node = poolList.firstChild;
	while(node)
	{
		// if the poolBlock is "selected" then unselect it.
		if (dojo.hasClass(node,"selected"))
		{
			dojo.removeClass(node, 'selected');
		}
		node = node.nextSibling;
	}*/
	
	// 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 pool 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)
{
    poolId = machineElement.parentNode.getAttribute('poolId');
    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)
{
    poolId = poolType.parentNode.getAttribute('poolId');
    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)
{
    appId = app.options[app.selectedIndex].value;
    var newUrl = url + '/' + appId + '/versions/';
    getLink(newUrl, null);
}

// Subclass of the Roller widget, with customized animation settings for the 
// news ticker on the pool list.
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();
    }
});

