//////////////////////////////////////////////
// CONFIGURATION ///////////////////////////
//////////////////////////////////////////////

  // make sure $() is still reserved to prototype
  // jQuery.noConflict();
  
  // Facebox
  jQuery.facebox.settings.opacity = 0.3;



//////////////////////////////////////////////
// BEHAVIORS ///////////////////////////////
//////////////////////////////////////////////

  // Automatic Ajax Spinner
    
  Ajax.Responders.register({
    onCreate: function() {
      if($('ajax_loading') && Ajax.activeRequestCount > 0){
        Element.show('ajax_loading');
      }
    },
    onComplete: function() {
      if($('ajax_loading') && Ajax.activeRequestCount == 0){
        Element.hide('ajax_loading');
      }
    }
  });


//////////////////////////////////////////////
// GLOBAL FUNCTIONS //////////////////////////
//////////////////////////////////////////////


  function isString() {
    return (typeof arguments[0] == 'string')
  }
  
  // JSON related
  
  function json_post(form_or_url, data, callback) {
		// shift arguments if data argument was ommited
		if ( jQuery.isFunction( data ) ) {
			callback = data;
			data = null;
		}
		    
    if (isString(form_or_url)) {
      url = form_or_url
    } else {  
      // received a form. Overriding data
      url = form_or_url.action;
      data = jQuery(form_or_url).serializeArray();
    };

    json_request("POST", url, data, callback);    
  }	
  
  function json_get(form_or_url, data, callback) {
		// shift arguments if data argument was ommited
		if ( jQuery.isFunction( data ) ) {
			callback = data;
			data = null;
		}
		
    if (isString(form_or_url)) {
      url = form_or_url
    } else {  
      // received a form. Overriding data
      url = form_or_url[0].action;
      data = jQuery(form_or_url).serializeArray();
    };		
    
    json_request("GET", url, data, callback);    
  }
    
  function  json_request(type, url, data, callback) {
    // TODO: if data is a String
    if (data==null) { data={}; }
    
    // if it's an Array (on POST)
    if (jQuery.isArray(data)) {
      data[data.length]={ name:'format', value:'jsonh'};
    } else if (isString(data)) {

      // VERY UGLY HACK
      parts = url.split("?")
      str_len = parts[0].length
      ext = parts[0].substring(str_len-3, str_len-1);
      if(ext != ".js"){
        data = data + "&format=jsonh";
      }
      // END VERY UGLY HACK
      
    } else {
      data['format']='jsonh';
    }

    json = {};
    
    jQuery.ajax({
      type: type,
      url: url,
      data: data,
      // dataType: "json",
      complete: function(event, xhr) {
        if (event.responseText==' ') {
          json = {};
        } else {
          
          // VERY UGLY HACK
          try{
            json = window["eval"]("(" + event.responseText + ")");
          }
          catch(e){ // BUG: not all requests are in the jsonh format
            json = {};
            window["eval"](event.responseText);
          };
          // END VERY UGLY HACK
        }

        // Standardize success response to 'ok' to facilitate callback
        if (jQuery.httpSuccess(event)) { 
          json.success = true;
        } else {
          json.success = false;
        };
        
        // ex: '401 Unauthorized'  ->  401
        json.status = parseInt(json.status);
        AJAX_callbacks(json, callback);
      }
    });    
  }
      
  function AJAX_callbacks(json, callback) {
    if (json.status == 401) {
      window.location = '/register';
      return false;
    }
    
    load_functions_from_JSON(json);
    if (jQuery.isFunction(callback)) { callback(json) };
    load_flash_from_JSON(json);    
    load_behaviors_from_JSON(json);    
  }
  
  // Adds the .json extension to the request. 
  function append_json_extension(url) {
    parts = url.split("?");
    request = parts[0];
    params = parts[1];

    json_request_url = request + ".json";
    if(params){ 
      json_request_url += "?" + params; 
    }

    return json_request_url;
  }
  
  // Part of a hack
  function append_js_extension(url) {
    parts = url.split("?");
    request = parts[0];
    params = parts[1];

    json_request_url = request + ".js";
    if(params){ 
      json_request_url += "?" + params; 
    }

    return json_request_url;
  }
  
  function load_functions_from_JSON(json) {
    window.eval(json.functions);
  }
  
  function load_behaviors_from_JSON(json) {
    window.eval(json.behaviors);
  }
  
  function load_flash_from_JSON(json) {
    if (json.flash) {
      str = '<div id="facebox_flash">'
      
      jQuery.each(json.flash, function(key, value) {
        str += '<ul class="' + key + '">';
          str += '<li>' + value + '</li>';
        str += '</ul>';
      });
      
      str += '</div>'
      
      if (jQuery('#facebox_flash').length>0) {
        jQuery('#facebox_flash').replaceWith(str);
      } else {
        jQuery('#facebox .content').prepend(str);
      };
    };
  }
    
  function load_body_from_JSON(json, element) {
    element = $(element);
    Element.update(element, json.body);
    element.show();
  }
  
  function loadJS(file) { 
    var script = document.createElement('script'); 
    script.src = file; 
    script.type = 'text/javascript'; 
    document.getElementsByTagName('head')[0].appendChild(script); 
    $j.log("Loading JS: " + file);
  };

  

/////////////////////////////////////
////////// jQuery Extensions ////////
/////////////////////////////////////

(function($){
  
  $.log = function(msg){
    if(window.console){
      console.log(msg);
    }
  };
  
  // Adds the .jsonh extension to the request. 
  $.appendJsonhExtension = function(url) {
    if(url.match(/\.jsonh/)){
      return url;
    }
    
    parts = url.split("?");
    request = parts[0];
    params = parts[1];

    json_request_url = request + ".jsonh";
    if(params){ 
      json_request_url += "?" + params; 
    }

    return json_request_url;
  };
  

  // Standard alchemy jsonh request
  $.jsonhRequest = function(options){
    // Add default response functions that just log to console.
    // The success/error functions below should be passed in, but 
    // in case it isn't, we'll default them to the following.
    var successCallback = options.success || function(jsonResponse){
      $.log("Request Successful");
      $.log(jsonResponse);
    };
    
    var errorCallback = options.error || function(jsonResponse){
      $.log("Request Error");
      $.log(jsonResponse);
    };


    options.success = function(jsonResponse){
      if(jsonResponse.status == "redirect"){
        window.location = jsonResponse.to;
      }
      else {
        successCallback(jsonResponse);
      }
    };
    
    options.error = function(XMLHttpRequest, textStatus){
      if(XMLHttpRequest.status == 400){
        jsonResponse = window["eval"]("(" + XMLHttpRequest.responseText + ")");
        errorCallback(jsonResponse);
      }
      else{
        $.log("Request error: " + textStatus);
        $.log(XMLHttpRequest);
      }
    };

    options = $.extend({ type: "POST" }, options || {});
    
    // Make sure the dataType that comes back in the success callback is json
    options.dataType = "json";
    
    // Make sure the call is using the jsonh format
    options.url = $.appendJsonhExtension(options.url);
  
    // Make the ajax call.
    $.ajax(options);
  };

})(jQuery);

// // Default success function. This function should rarely change.
// // If you need finer control, then override it in the options.
// success: function(jsonResponse){
//   if(jsonResponse.status == "redirect"){
//     // Redirect to a new location
//     window.location = jsonResponse.redirect_to;
//   }
//   else if(jsonResponse.status == "ok"){
//     options.requestSuccess(jsonResponse);
//   }
//   else {
//     options.requestError(jsonResponse);
//   }
// },
// 
// // Default error callback. Override if you need another setting.
// error: function(xmlHttpRequest, textStatus){
//   $.log("=== Application Request Error ===");
//   // $.log("responseText: ");
//   // $.log(xmlHttpRequest.responseText);
//   $.log(xmlHttpRequest);
//   $.log("textStatus: " + textStatus);
//   $.log("status: " + xmlHttpRequest.status);
//   $.log("=== Application Request Error ===");
// }


// not sure if used below this...



// Lead Gen "learn more" link
function toggle_extended_descriptions( id, dom_obj ) {
  var extended_dec = $('offer_' + id + '_extended_description');
  extended_dec.toggle();
  if(extended_dec.style.display == 'none'){ 
    dom_obj.innerHTML = "Learn more...";
  }
  else {
    dom_obj.innerHTML = "(X) Close";
  }
}

/* Product Review Related */

function check_all(name)
{
  var checkboxes = document.getElementsByName(name);
  for(i=0; i < checkboxes.length; i++)
  {
    checkboxes[i].checked = 'checked';
  }
}

function check_none(name)
{
  var checkboxes = document.getElementsByName(name);
  for(i=0; i < checkboxes.length; i++)
  {
    checkboxes[i].checked = '';
  }
}

function cloneEmailNode() {
	var node = $('node_to_clone');
	var cloned = node.cloneNode(true);
	cloned.getElementsByTagName('input')[0].value = '' // erase any current value

	if ($('container').childNodes.length <= 10) {
		$('container').appendChild(cloned);
	}
}


/* Feeds Hover */
var timeout     = 500;
var closetimer  =   0;
var ddmenuitem  =   0;

// open hidden layer
function mopen(id)
{
 // cancel close timer
 mcancelclosetime();

 // close old layer
 if(ddmenuitem) ddmenuitem.style.display = 'none';

 // get new layer and show it
 ddmenuitem = document.getElementById(id);
 ddmenuitem.style.display = 'block';

}
// close showed layer
function mclose()
{
 if(ddmenuitem) ddmenuitem.style.display = 'none';
}

// go close timer
function mclosetime()
{
 closetimer = window.setTimeout(mclose, timeout);
}

// cancel close timer
function mcancelclosetime()
{
 if(closetimer)
 {
 window.clearTimeout(closetimer);
 closetimer = null;
 }
}

// close layer when click-out
document.onclick = mclose;

function displayPopUpSmartly(hoverElementId, elementId){
  // The element the mouse will hover to activate the popup.
  hoverElement = $(hoverElementId);
  hoverElementWidth = hoverElement.getWidth();
  hoverElementHeight = hoverElement.getHeight();
  hoverElementX = hoverElement.positionedOffset().first();
  hoverElementY = hoverElement.positionedOffset().last();

  // Pop up element Vars
  popUpElement = $(elementId);
  popUpElementHeight  = popUpElement.getHeight();
  popUpElementWidth   = popUpElement.getWidth();
  
  // Move element to set position
  defaultX = hoverElementX + (hoverElementWidth * 0.6);
  defaultY = hoverElementY + (hoverElementHeight * 0.6);
  
  popUpElementLeftX = popUpElement.viewportOffset().first();
  popUpElementRightX = popUpElementLeftX + popUpElementWidth;
  
  popUpElementTopY = popUpElement.viewportOffset().last();
  popUpElementBottomY = popUpElementTopY + popUpElementHeight;

  // Check the X positions
  if( (popUpElementLeftX < 0) || (popUpElementRightX > document.viewport.getWidth()) ){
    defaultX = hoverElementX + (hoverElementWidth * 0.3) - popUpElementWidth;
  }
  
  // Check the Y positions
  if( (popUpElementTopY < 0) || (popUpElementBottomY > document.viewport.getHeight()) ){
    defaultY = hoverElementY + (hoverElementHeight * 0.3) - popUpElementHeight;
  }
  
  // After all margins are set, display popUpElement.
  popUpElement.setStyle({"top" : defaultY + "px", "left" : defaultX + "px"});
}




// Common check all behavior.  Use as follows:

var CheckAll = Behavior.create ({
  checkboxes : null,
  initialize : function(check_box_location){
    this.checkboxes = check_box_location;
  },
  onclick : function(e) {
    checked = this.element.checked;
    $$(this.checkboxes).each(
      function(o){
        o.checked = checked;
      }
    )
  }
})


// Used on Profile edit_basic page

function mark_for_destroy(e) {
  element = $(e).up('.has_many_element');
  element.down('.should_destroy').value = 1;
  element.hide();
}




