jQuery.polypage = {
	
	states: null, 
	
	init: function(defaults){
		this.assignDisplayStyles();
		this.buildOptionsBar();
		this.setStartValues(defaults);
		this.refresh();
	},
	
	setStartValues: function(initValues){
		if(initValues) {
			for(var i in initValues) {
				if(jQuery.cookie()){ 
					if(jQuery.cookie(initValues[i]) != 'yes') {
						// only set the initial value if it isnt already set 
						// otherwise setState will toggle off
						this.setState(initValues[i],true);
					} 
				} else {
					// if cookies are not being used set as usual
					this.setState(initValues[i],true);
				}
					
			}
		};
		var hashValues = window.location.hash.replace(/^#/,'').split(/_and_/);
		for(var i in hashValues) {
			// if it is on, turn it off 
			var val = (this.states[hashValues[i]]) ? false : true;
			// if it has been set elsewhere then the cookie also will be toggled
			this.setState(hashValues[i],val);
		}
	},
	
	findStates: function(){
		var el = this.findAll();
		var self = this;
		this.states = {};
		el.each(function() {
			var s = self.extractDataFromClassName(jQuery(this).attr('class'));
			var states = s.split(/_?not_|_or_|_and_/);
			for(var state in states) {
				if(self.states[states[state]]==undefined && states[state]!='' ) {
					if(jQuery.cookie()){ 
						// the state may be undefined but if the state has been set on another page 
						// we need to reset that state in our array to be on
						if(jQuery.cookie(states[state]) == 'yes') {
							self.states[states[state]]=true;
						} else {
							self.states[states[state]]=false;
						}
					} else {
						// if we are not using cookies if its not in our aray we dont know about it
						self.states[states[state]]=false;
					}
				}
			}
		});
		return this.states;
	},
	
	extractDataFromClassName: function(className){
		var classes = className.split(' ');
		for(var i in classes)
			if(classes[i].match(/pp_/)) return classes[i].replace(/pp_/,'');
		return '';
	},
	
	findAll: function(){
		return jQuery("*[@class~='pp_']");
	},
	
	refresh: function(){
		var self = this;
		this.findAll().each(function(){
			self.evaluateNode(this);
		});
	},
	
	assignDisplayStyles: function(){
		this.findAll().each(function() {
			$(this).css('display',$(this).css('display'));
		});
	},
	
	evaluateNode: function(node){
		// a node is an element with the pp_ class
		var on = this.evaluate(this.extractDataFromClassName(jQuery(node).attr('class')));	
		// toggle on or off if to be displayed
		if(on) jQuery(node).show();
		else jQuery(node).hide();
		return on;
	},
	
	evaluate: function(input){
		var str = input
			.replace(/^pp_/gi,'')
			.replace(/_and_/gi,' && ')
			.replace(/_or_/gi,' || ')
			.replace(/_?not_/gi,' !')
			.replace(/([a-z_]+)/gi,"this.states['$1']");
		return eval(str);
	},

	setState: function(state,val){
		this.states[state] = val ? true : false;
		jQuery('#pp_state_switch_'+state).toggleClass('active');
		
		// if the state needs to be set regardless of if it has been set already 
		// then the setState function is not the way to do it as it will toggle the state
		this.toggleCookie(state);
		this.refresh();
	},
	
	toggleCookie: function(state) {
		if(jQuery.cookie() && (state != '')){ 
			if((jQuery.cookie(state) == null) || (jQuery.cookie(state) != 'yes')) {
				// cookie never been set, set the cookie
				jQuery.cookie(state, 'yes', {"path":"/"});
			} else {
				// destroy the cookie
				jQuery.cookie(state, null, {"path":"/"});
			}
		}
	},
	
	buildOptionsBar: function(){
		this.findStates();
		var self=this;
		jQuery('body').append('<div id="pp_options"><ul></ul></div>');
		
		// it would be really cool if the object was sorted alphabetically 
		// currently it depends on the order of the classes in the page
		// in usability testing this inconsistancy could be confusing
		
		//this.states = this.states.sort();
		
		for(var s in this.states) {
			var state = s;
			var val = this.states[state];
			
			// show hide options
			jQuery('#pp_options ul').append('<li><a href="#'+state+'" id="pp_state_switch_'+state+'">'+state.replace(/_/,' ')+'</a></li>');
			
			if(jQuery.cookie()){ 
			// If we are using cookies, check cookies, 
			// if there is a positive cookie set then switch the state to be on and refresh
				if((jQuery.cookie(state) != null) || (jQuery.cookie(state) == 'yes')) {
					// this state should be on because there is a cookie set
					this.states[state] = true;
					jQuery('#pp_state_switch_'+state).toggleClass('active');
					this.refresh();
				}				
			}
			
			// switch event
			jQuery('#pp_state_switch_'+state)
				.click(function() {
					var state = jQuery(this).attr('id').replace('pp_state_switch_','');
					self.setState(state,!self.states[state]);
					return false;
				});
		};
	},
	
};