/*
   Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work
   of Simon Willison (see comments by Simon below).

   Description:
   	
   	Uses css selectors to apply javascript behaviours to enable
   	unobtrusive javascript in html documents.
   	
   Usage:   
   
	var myrules = {
		'b.someclass' : function(element){
			element.onclick = function(){
				alert(this.innerHTML);
			}
		},
		'#someid u' : function(element){
			element.onmouseover = function(){
				this.innerHTML = "BLAH!";
			}
		}
	};
	
	Behaviour.register(myrules);
	
	// Call Behaviour.apply() to re-apply the rules (if you
	// update the dom, etc).

   License:
   
   	This file is entirely BSD licensed.
   	
   More information:
   	
   	http://ripcord.co.nz/behaviour/
   
*/   

var Behaviour = {
	list : new Array,
	
	register : function(sheet){
		Behaviour.list.push(sheet);
	},
	
	start : function(){
		Behaviour.addLoadEvent(function(){
			Behaviour.apply();
		});
	},
	
	apply : function(){
		for (h=0;sheet=Behaviour.list[h];h++){
			for (selector in sheet){
				list = document.getElementsBySelector(selector);
				
				if (!list){
					continue;
				}

				for (i=0;element=list[i];i++){
					sheet[selector](element);
				}
			}
		}
	},
	
	addLoadEvent : function(func){
		var oldonload = window.onload;
		
		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				oldonload();
				func();
			}
		}
	}
}

Behaviour.start();

/*
   The following code is Copyright (C) Simon Willison 2004.

   document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names, 
     class names and ids and can be nested. For example:
     
       elements = document.getElementsBySelect('div#main p a.external')
     
     Will return an array of all 'a' elements with 'external' in their 
     class attribute that are contained inside 'p' elements that are 
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails 
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words 
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    
    if (!currentContext[0]){
    	return;
    }
    
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained 
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute 
   Tag
*/

/* behaviour.js rules
----------------------------------------------*/
var win = null;
function open_popup_dimensions(width,height,url,name) {
	win = window.open(url, name, 'toolbar=0, location=0,directories=0, status=0, menubar=0, scrollbars=1, resizable=1, width=' + width + ', height=' + height + ', top=0, left=0');
	win.focus();	
}

// Uses the prototype library
function activate(id) {
    // Modifiy the classes on the top images
	var allNodes = document.getElementsByClassName('album_border_link_active', 'image_album');
	allNodes.each(function(node){
	   if(node.className == 'album_border_link_active') {
	    node.className = 'album_border_link_visited';
	   }else{
	    node.className = 'album_border_linkl';
	   }	   
	});
	
	// Hide the current main image
	var bigImageNodes = document.getElementsByClassName('show_me', 'image_album_main');
	bigImageNodes.each(function(node){
        node.className = 'hide_me';
	});
	
	$(id + '_large').className = 'show_me';
	$(id).className = 'album_border_link_active';	
}

// Converts a price in cents to a currency
function number_to_currency(price_in_cents) {
    var price = price_in_cents + '';
    var length = price.length;
    switch(length) {
        case 1:
            price = '$0.0' + price;   
            break;
        case 2:
            price = '$0.' + price;
            break;
        default:
            price = '$' + price.substring(0, length-2) + '.' + price.substring(length-2, length);
            break;
    }
    return price;
}

// Sets the order prices
function set_order_prices() {
    var total_price = 0;
    var allNodes = document.getElementsByClassName('order_select', 'order_table');     	
    allNodes.each(function(node){        				   
       total = (node.id.substring(5)*1) * (node.options[node.selectedIndex].value*1);        	   
       $(node.name + '_total').innerHTML = number_to_currency(total);
       total_price += total
      
    });			
    $('total_price').innerHTML =  number_to_currency(total_price);
}

// Getting number of days in a month
function days_in_month(year, month) {
    return 32 - new Date(year, month, 32).getDate();
}

/*
    Adjusted days in a specific Ruby on Rails generated date_select field
    params
        parent_tag: a parent tag that contains the three date_select fields
        objec_name: name of the object class in lowercase
*/
function adjust_days(parent_tag, object_name, field) {
    var day = 0;
    var month = 0;
    var year = 0;              
    var someNodes = $(parent_tag).getElementsByTagName('select');
    var nodes = $A(someNodes);                               
    nodes.each(function(node) {
        if(node.name == object_name + "[" + field + "(1i)]") {
            year = node.options[node.selectedIndex].value;
        }                     
        if(node.name == object_name + "[" + field + "(2i)]") {
            month = node.options[node.selectedIndex].value;
        }
        if(node.name == object_name + "[" + field + "(3i)]") {
            day = node;
        }                                                       
    });
    var current_day = day.options[day.selectedIndex].value;
    var days = days_in_month(year, month-1);
    
    // Adjust current day to max day if new max days is smaller than current day
    if(current_day > days) {
        current_day = days
    }
    
    // Remove day options
    var length = day.options.length              
    for(var i = 0; i < length; i++) {
        day.remove(0);
    }
    
    // Create new day options
    for(var i=0; i < days; i++) {
    	day.options[i] = new Option(i+1,i+1);
    	if((i+1) == current_day) {
    		day.options[i].selected = "selected";
    	}
    }                   			     
}

/* Close a popup window */
function close_now() {
	this.focus();
	self.opener = this;
	self.close();
	window.close();
}

/* Shows a indicator and disables submit button when submitting a listing */
function listing_submit() {
    $('listing_submit_button').disabled = 'disabled';
    $('indicator').style.display = 'block';
}

// Used so form can only be submitted once
var submitted = 0;

var myrules = {
		/* Generic */
		'.popup_link' : function(element) {
			element.onclick = function() {
				open_popup_dimensions(610, 377, this.href + "?popup=true", 'popup');
				return false;
			}	
		},
		/* Image Popup */
		'.image_link' : function(element) {
			element.onclick = function() {
				open_popup_dimensions(400, 400, this.href, 'album');
				return false;
			}	
		},
		/* Product Popup */
		'.product_link' : function(element) {
			element.onclick = function() {
				open_popup_dimensions(610, 377, this.href, 'product');
				return false;
			}	
		},		
		/* Map Popup */
		'.map_link' : function(element) {
			element.onclick = function() {
				open_popup_dimensions(720, 497, this.href, 'map');
				return false;
			}	
		},		
		/* Album Display Image */
		'.album_border_link' : function(element) {
			element.onclick = function() {
				activate(this.id)
				return false;
			}	
		},
		'.album_border_link_active' : function(element) {
			element.onclick = function() {
				activate(this.id)
				return false;
			}	
		},
		'.album_border_link_visited' : function(element) {
			element.onclick = function() {
				activate(this.id)
				return false;
			}	
		},
		'#change_user_listing_role' : function(element) {
			element.onchange = function() {			  
				window.location.href = "/admin/users/list/" + this.options[this.selectedIndex].value;
				return false;
			}	
		},
		/* Used for Order from for Landlords */
		'.order_select' : function(element) {
			element.onchange = function() {	
                set_order_prices();
    			return false;
			}	
		},
		/* Used to submit a form only once */
		'.submit_form' : function(element) {
			element.onsubmit = function() {	
			    if(submitted == 0) {			       
                    submitted += 1;                    
                    return true;
    			}else{
    			    return false;    
    			}
			}	
		},
		/* Used to make sure days are correct for available listing date in select boxes */
		'#listing_available select' : function(element) {
			element.onchange = function() {	                 
                adjust_days('listing_available', 'listing', 'available');
            }
		},
		/* Used to make sure days are correct for close_date listing date in select boxes */
		'#listing_close_date select' : function(element) {
			element.onchange = function() {	                 
                adjust_days('listing_close_date', 'listing', 'close_date');
            }
		},		
		/* Used to make sure days are correct for user close date */
		'#user_close_date select' : function(element) {
			element.onchange = function() {	                 
                adjust_days('user_close_date', 'user', 'close_date');
            }
		},		
	   /* Close Window */
	   '.close_window' : function(element) {
			element.onclick = function() {
			 close_now();
			 return false;
			},
			element.onmouseover = function() {
			 this.style.color = "#f68e20";
			},
			element.onmouseout = function() {
			 this.style.color = "#17416A";
			}			
	   },
	   '#check_box_checked' :function(element) {
	       element.onsubmit = function() {
	           if($('js_checkbox').checked) {
	               listing_submit();
	               return true;
	           }else{
	               alert('Are you sure your listing details are correct?');
	               return false;
	           }
	       }
	   },
	   '#listing_submit' :function(element) {
	       element.onsubmit = function() {
               listing_submit();
	           return true;         
	       }
	   },	   
	   '.search_form_button' :function(element) {
	       element.onclick = function() {
	           var b = Try.these( 
	               function() { 
	                   $('search_form').submit();                    
	                   return true;
	               }
	           ) || false;
	           if(b) { 
	               return false;
	           }else{
	               return true;
	           }          
	       }
	   }	   	   																													
	};
	Behaviour.register(myrules);
