/*
 * Authors : Colin Young and Peter Nguyen
 * Description : AAIIjs - set of Javascript classes for the AAII.com website
 * Usage : see documentation
 * Requires : Mootools & Mootools.More versions 1.2.3 or higher (http://mootools.net)
 */

	//var $ = document.id; // Dollar Safe Mode

	window.addEvent('domready', function () {

	/********************************
	 |    Initiate JS Class			|
	 *******************************/

    // the AAIIjs class accepts a few setup variables populated serverside
	AAII = new AAIIjs({
		basepath: '/'
	});
	
	/********************************
	|    Imports					|
	*******************************/
	 
    // "import" classes you need here (or on the fly)
	AAII.Forms = new Forms();
	AAII.Menus = new Menus();
    AAII.Shelf = new Shelf();
	AAII.SBox = new SBox();

	/********************************
	 |    Load Functions			|
	 |		(all functions to be	|
	 |		fired when the page		|
	 |		is first loaded)		|
	 *******************************/

	// start smoothscroller
	var Scroll = new SmoothScroll();
	
	// start notifications
	if ($chk($('flash'))) {
		//$('notifications').reveal();
		$('notifications').show();
	    $('notifications-dismiss').addEvent('click', function() {
			$('notifications').dissolve();
		});
		// hoverstates for notification box
		$("notifications").addEvents({
			mouseenter: function() {
				var myfx = new Fx.Tween(this, {property: "opacity", duration: "short"});
				myfx.start(1);
	
			},
			mouseleave: function() {
				var myfx = new Fx.Tween(this, {property: "opacity", duration: "short"});		
				myfx.start(.6);
			}
		});
	}
	
	if ($chk($('ajax_carousel')) ) {
		//if (!$("body").hasClass("ie7")) {
			AAII.Carousel = new Carousel($('ajax_carousel'));
		//}
	}
    if (!$("body").hasClass("ie6")) {
		$each($$('.horizontal-scroller'), function(i) {
			var s = new Scrollerize(i, 1);
		});
	}
    // expand links
    $each( $$('a[href*="expand"]'), function(i) {
		if (i.get('href').substr(0,1) == "#") {
			i.addEvent('click', function() {
				try {
					$$(".expand-1")[0].reveal();
					this.hide();
				} catch(e) {}
			});
        }
    });
    
    // object-types for stretching a la cnn
    
    zoomout = function(i, image, source, w, h) {
		var ins = $$("#" + i.get('id') + " .object-content a")[0];
        var image2 = ins.getChildren('img')[0];
        // effect
        image2.morph({'width': w});
        
        (function() {
            image2.set('src', source);
            ins.toggleClass('zoomed');
        }).delay(400);
        
        // hide overlay if it exists
        if (ins.getChildren('.icon-img-overlay').length !== 0) {
			ins.getChildren('.icon-img-overlay').destroy();
        }
        
        // reset events
        ins.removeEvents();
        ins.addEvent('click', function() { zoomin(ins.getParent().getParent()); return false;});
        
        return false;
    };    
    
    zoomin = function(i) {
        var ins = $$("#" + i.get('id') + " .object-content a")[0];
        var fullPath = ins.get('href');
        // load new image element                    
        var path = ins.getChildren('img')[0].get('src')+"";
        path = path.replace("small", "splash");
        var tmpimg = new Image();
        tmpimg.src = path;
        var oldimg = ins.getChildren('img')[0];
        
		var oldwidth = oldimg.getStyle('width');
		var oldheight = oldimg.getStyle('height');        
        var oldsrc = oldimg.get('src');
        
        // effect
        oldimg.morph({width: "435px"});
        
        (function() {
			// store old values
                
            // overlay for full view
	        var d = new Element('div', {
				"class" : "icon-img-overlay",
				html: '<a href="'+fullPath+'">Click here to view full image.</a>',
                events: {
					'click' : function() { ins.removeEvents(); window.location = fullPath },
					'mouseenter' : function() { d.getChildren('a')[0].setStyle('cursor', "pointer"); },
					'mouseleave' : function() { d.getChildren('a')[0].setStyle('cursor', ""); }
                }                
	        });
			ins.grab(d, "top");
                
            // do effect
            oldimg.set('src', path);
            ins.toggleClass('zoomed');
            ins.removeEvents();
            
            ins.addEvent('click', function() { zoomout(i, oldimg, oldsrc, oldwidth, oldheight); return false;});
        }).delay(400);
        
        // set 'zoom out' effect and 
      
        return false; //always
    };
    

    
    $each( $$('.object-type.icon-img'), function(i) {
    	if (!i.hasClass('generated-splash') && !i.hasClass('splash') && i.hasClass('left')) {
        	var figures = $$("#" + i.get('id') + " a");
        	$each( figures, function(j) {
				if (!j.getParent().hasClass("object-caption") && !j.getParent().getParent().hasClass("object-caption")) {
	            	j.addEvent('click', function() {zoomin(i); return false;});
				}
            });
        }
    });
    
	if ($$(".share-pop").length > 0) {
		Sharepops();	
	}
   
	// searchbox onfocus behavior
	
	// scroll listeners
	/* scrollspy instance 
	var ss_targets = $$(".article-tools");
		
	if (ss_targets.length == 1) {
		
		window.removeEvent('scroll');
		window.addEvent('scroll', scrollEvent);
		
		var ss = new ScrollSpy({
			min: 415,
			onEnter: function() {
					console.log("onenter");
					var item = ss_targets[0];
					if (window.getSize().x > 1300 && shouldMakeFixedTest(item)) {
						item.setStyle('position', 'fixed');
						item.setStyle('top', '15px');
					}
			},
			onLeave: function() {
					var item = ss_targets[0];
					item.setStyle('position', 'absolute');
					item.setStyle('top', '0px');
			},
			container: window
		});
	}
	
	function shouldMakeFixedTest(el) {
		if (window.getSize().x < 1300) {
			el.setStyle('position', 'static');			
			return false;	
		}
		var totalPageSize = window.getScrollSize().y;
		var currentScrollY = window.getScroll().y;
		var heightofEl = el.getSize().y;
		var heightofFooter = $("footer").getSize().y;
		var heightofComments = $$("div.comments")[0].getSize().y;
		var viewportHeight = window.getSize().y;
		var totalBottomPadding = viewportHeight+heightofEl+heightofFooter+heightofComments+250;		
		if (totalPageSize - currentScrollY < totalBottomPadding ) {
			var newheight = totalPageSize - totalBottomPadding;
			el.setStyle('top', newheight + "px");
			el.setStyle('position', 'absolute');
			return false;
		}
		if (parseInt(el.getStyle('top')) > 20) {
			el.setStyle('position', 'fixed');
			el.setStyle('top', '15px');
		}
		return true;
	}
	
	function scrollEvent(e) {
		if (shouldMakeFixedTest(ss_targets[0]) && window.getScroll().y > ss.min)
			ss.fireEvent('onEnter');
	}*/
	
	/*
	*
	* Load user's name and state into comments
	*/
	if ($chk($("comment-state"))) {
		CommentForm();
	}

});

// ==== END OF ONLOAD ACTIONS ====



// -------------------------------------------------------------------------------------------------------
// Class Library (eventually should be split into separate files then combined and compressed for release)
// -------------------------------------------------------------------------------------------------------

	/************************************************
	 |    General Functions for AAII Object			|
	 |	  > Conditionals, default properties, etc	| 	 
	 ***********************************************/
	 
AAIIjs = new Class({
	Implements: [Options, Events],
    options:  {
    		basepath: "/",
			isArticle: false,
			isRestricted: false
    },
    initialize: function(options){
    	this.setOptions(options);
    }
});

Forms =  new Class({
	Extends: AAIIjs,
    initialize: function(options){
    	this.parent(options);
    	
		$("searchbox").value="Search AAII..."; // stop those autofill things
		this.replaceOnClick($('searchbox'));
		//this.searchWhileTyping($('searchbox'));
		this.loginStart();		
    	// persistent storage
		window.Forms = this;
    },
    
	/* Function Description: Replaces the value of an input element with a blank value ("") only if it is equal to its default (starting) value.
     * @args: element object
     * @returns: void
     */
    replaceOnClick: function(el){
        if (!el.started) {
	        el.startValue = el.value;
        }
    	el.addEvent('focus', function() {
        	if (el.value === el.startValue) {
            	el.value = "";
            }
            el.started = true;
        });
        el.addEvent('blur', function() {
			if (el.value === "") {
				el.value = el.startValue;
			}
		});
    },
	/* Function Description: Starts the AJAX Search Box.
     * @args: element object
     * @returns: void
     */	
	searchWhileTyping: function(el){
		el.addEvents({
			focus: function() {
				if (!$self.searchmenuStatus) {
					var dropdownBox = new Element('div', {
						'class': 'waiting',
						'text': 'Waiting...',
						'id': 'searchmenu',
                        events: {
                         mouseenter: function() {
			            	$self.mouseInSearch = true;
            			    console.log("entering");
				            },
			            mouseleave: function() {
			            	$self.mouseInSearch = false;
            			    console.log("leaving");
				            }
                        }
					});
				}
				$('search').adopt(dropdownBox);
				var slide = new Fx.Morph(dropdownBox);
				slide.start({'height' : '20px', 'opacity' : 1.0});
				$self.searchmenuStatus = true;
			},
			blur : function() {
				if ($self.searchmenuStatus && !$self.mouseInSearch) {
					$('searchmenu').nix();
					$self.searchmenuStatus = false;
				}
			},
			keyup: function() {
				var menu = $('searchmenu');
                SearchRequestLoading = false; // global var
                
				if ($("searchbox").value.length < 1 ) { 
					menu.set('class', 'waiting');
					menu.set('html', 'Waiting...');
				} else if ($("searchbox").value.length < 3 ) {
					var menu = $('searchmenu');
					$('searchmenu').set('class', 'loading');
					(function(){menu.set('class', 'loaded');}).delay(400);
					menu.set('html', "Searching: "+'<b>'+$("searchbox").value+"</b>");					
				} else {
					menu.set('class', 'results');
					menu.set('html', "Searching: "+'<b>'+$("searchbox").value+"</b>");                    
                    if (!SearchRequestLoading) {
                    	var searchValue = $("searchbox").value.replace(/[^\d\w]/gi, "+");
	                    var r = new Request.JSON({url: "/search/general/"+searchValue,
                        	onSuccess: function(json) {
                                if ($chk($("SearchResultsUL")))
                                        $("SearchResultsUL").empty();
                                        
                                var slide = new Fx.Morph($('searchmenu'), {duration:200});
                                var currH = $('searchmenu').getStyle('height');
                                var toH = 20+(json.results.length*60);
                                slide.start({'height' : [currH, toH], 'opacity' : 1.0});
                            	SearchRequestLoading = false;
                                if (!$chk($("SearchResultsUL"))) {
	                                SearchResultsUL = new Element("ul", {"class":"results", id: "SearchResultsUL"});
	                               	menu.adopt(SearchResultsUL);
                                }
      							$each(json.results, function(i, index) {
									$("SearchResultsUL").adopt(new Element('li', {html: '<a href="' + i.url + '">'+i.title+'</a>'}));
                                });
                            },
                            onFailure: function() {},
                            onRequest: function() {
                            	SearchRequestLoading = true;
                                if ($chk($("SearchResultsUL")))
                                	$("SearchResultsUL").empty();
                            },
                            method: "get"
                        }).send();
                    }
				}
			}
		});
	},
	/* Function Description: Login Box hover event setup and population.
     * @args: null
     * @returns: void
     */ 
	loginStart: function() {

		var el = $('bpLogin');
		var box = $('bpLoginBox');
		if ($chk($('bpLogin'))) {
			el.set({
				href: 'javascript:void(0);',
				events: {
					"click": function() {
						loc = window.location.href;
						//if (loc.indexOf("member") > 0 ) // if member is present in string
						//	window.location="/home/index";
						//else
						//	window.location="/home/member";
	
						box.setStyles({'display': 'block', 'visibility':'visible', 'opacity':0});				
						box.fade(1);
						(function(){$('constitname').focus();}).delay(400);
					}
				}
	
			});	
		}			
	},
	closeLogin: function() {
					(function(){$('bpLoginBox').set('display', 'none');}).delay(200);
					$('bpLoginBox').fade(0);	
	}
    
});

var Menus =  new Class({
	Extends: AAIIjs,
    initialize: function(options){

    	this.parent(options);
		if (!/MSIE 6/.test(navigator.userAgent)) {
		this.startTopNav();
		}
		this.memberLogin();
    },
	/* Function Description: Turns a set of divs into an accordion
     * @args: array togglers, array content
     * @returns: void
     */
    startTopNav: function() {
	
		/* top nav elements themselves:
			- on mouseover, show their sibling ul
			- on mouseout, hide their sibling ul
		*/
		var collection = $$('#top-links ul a');
		// loop and add mouse events
		$each(collection, function(item) {
			if (!item.getParent(".top-links-sub")) {
				item.addEvent("mouseenter", function() {
					window.firing = item;
					(function() {					
					if (window.firing == item) {
							window.firing = false;
							// resets
							$$(".top-links-sub").hide();
							$$('#top-links a').removeClass("current")
						
							item.getSiblings("ul").show();
							item.addClass("current");
						}
					}).delay(110);
				});
				item.addEvent("mouseleave", function() {
					window.firing = false;
				});				
			}
		});
		/* top nav itself:
			- on mouseout, reset options */
		var topnav = $("top-links");
		topnav.addEvent("mouseleave", function() { // must be mouseleave.
			if (!window.firing) {
				(function() {
					if (!window.firing) { // is mouse STILL off?
							// reset 
							$$(".top-links-sub").hide();
							$$('#top-links a').removeClass("current");
							// redo
							$$('#top-links ul.first').show();
							$$('#top-links a.currentpage').addClass('current');
					}
				}).delay(600);
			}
		});
	},
	// if member-login exists, set up the "unfolding"
	memberLogin: function() {
		if ($chk($("member-login"))) {
			//
			var link = $$("#member-login a")[0];
			link.addEvent('click', function() {
				var div = $$("#member-login .content")[0];
				div.reveal();
				$("member-login").setStyle('height', 'auto');
				document.forms["member_login"].constitid.focus();
				this.nix();
			});		
		}
	}
});

var Carousel = new Class({
    options:  {
    	name: "AAII Carousel class"
    },
	Extends: AAIIjs,
    initialize: function(options){
    	this.parent(options);

		this.switching = false;
		this.pointerPosition = 1;
		this.paused = true;
		//this.myTimer = new Timer();
		//var intervalID = this.checkTimer.periodical(5000);
		
		
		this.carousel = $("ajax_carousel");
		this.carousel.file = $("ajax_carousel").get("file");
		this.carousel.mode = $("ajax_carousel").get("mode");
		this.carousel.path = "/carousels/" + this.carousel.file + "/" + this.carousel.mode;		
		this.carousel.loader_right = new Element('span', {
			id: "carousel_loader_right",
			styles: {
				"float" : "right",
				"display" : "block",
				"padding-right" : "30px",
				"text-indent": "-9000px",
				"background" : "url(/images/carousel/loader.gif) no-repeat"
			},
			text: "loading"
		});
		this.carousel.loader_left = this.carousel.loader_right.clone().setStyle('float', 'left').set('id', "carousel_loader_left");
		this.images = $('carousel_image');
			this.imageWidth = "397";
		this.content = $('carousel_content');		
		this.title = $('carousel_title');
		this.controls = $('carousel_controls');
		this.scroller = $('carousel_image_mask');
		
		this.current = 0;
		
		this.delay = 6000 + 600 + 2000;
		
		$self = this;		
		// useful later for globally stored values
		window.Carousel = this;
		
		// functions to fire when this class is loaded.  Will only be loaded on the home page.
		Util = new Util();
		
		this.start(options.target);		

	},
	loadNew: function(which) {
		var newPos = $self.imageWidth * (which);
		var currPos = $self.scroller.scrollLeft;
		var left = newPos - currPos;
		(function() {
		var fx = new Fx.Scroll($self.scroller, {
			wheelStops: false,
			offset: {
				'x': left
			}
		}).start()}).delay(150);
		//$self.scroller.morph({opacity: .3});	
		//(function() {$self.scroller.morph({opacity: 1})}).delay(400);
		
		$each($self.content.getChildren(), function(item) { 
			item.fade(0);
		});
		$each($self.title.getChildren(), function(item) { 
			item.fade(0);
		});
		$each($self.controls.getChildren(), function(item) { 
			if (item.get('id') !== "carousel_report") {
				item.fade(0);
			}
		});
		
		(function() {	
		$each($self.content.getChildren(), function(item) { 
			item.hide();
		});
		$each($self.images.getChildren(), function(item) { 
			item.hide();
		});		
		$each($self.title.getChildren(), function(item) { 
			item.hide();
		});
		$each($self.controls.getChildren(), function(item) { 
			if (item.get('id') !== "carousel_report") {
				item.hide();
			}
		});		
		$$('.carousel_slide_content')[which].show().fade(1);
		$$('.carousel_slide_title')[which].show().fade(1);
		$$('.carousel_slide_title')[which].show().fade(1);	
		$('slide_links_'+which).show().fade(1);
		$self.current = which;
		which++;
		$("carousel_report").set('html',which + " of " + window.slidesCount); 
	
		}).delay(200);
		
	},
	next: function() {
		var next = $self.current+1;
		if ($chk($$('.carousel_slide_image')[next]))
			$self.loadNew(next);
		else
			$self.loadNew(0);
	},
	prev: function() {
		var prev = $self.current-1;
		if ($chk($$('.carousel_slide_image')[prev]))
			$self.loadNew(prev);
	},
	/*
		void Start:
		
			- Set up sliding (<li>'s)
			- inject controls
	*/
	start: function(id) {
			// CONTROLS
			// add controls to controls div.
			// - load in from JSON
			// - add and display controls.
			
			// Why is this handled in JS? because we want it to degrade. People without JS 
			// should just see the first slide and no scroller.
			$self.scroller.scrollLeft =0;
			
			var req = new Request.JSON({url: $self.carousel.path,
				method: "get",
				onRequest: function() {
					//loading controls
					$self.controls.show(); //.setStyle('opacity', .6);
					$self.controls.adopt($self.carousel.loader_right);
				},
				onSuccess: function(r, rtext) {
					$("carousel_controls").empty();
					var size=  r.slides.length;
					window.slidesCount = r.slides.length;
					var report_div = new Element('div',
					{
						"id" : "carousel_report",
						text: "1 of " + r.slides.length,
						styles : {
							display: "block"
						}
					});
					
					$("carousel_controls").adopt(report_div);
					
					for (i = 0; i < size; i++ ) {
						var div = new Element('div', {
							id: "slide_links_"+i
						}); 
						// PREV LINK

						if (true) {
							var prev_num = i;	
							
							var prev = new Element('a', {
								'class': "prev",
								html: "",
								href: "javascript:;",
								events: {
									click: function() {
										$self.prev();
									}
								} 
							});		
                            prev.adopt(new Element('span', {"class":'corner prev_left'}));
                            prev.adopt(new Element('span', {"class":'corner prev_right'}));                            
							div.adopt(prev);	
						}	
									
						// NEXT LINK
						if (true) {
							var next_num = i +2;	
							
							var next = new Element('a', {
								'class': "next",
								html: "",
								href: "javascript:;",
								events: {
									click: function() {
										$self.next();
									}
								} 
							});
                            next.adopt(new Element('span', {"class":'corner next_left'}));
                            next.adopt(new Element('span', {"class":'corner next_right'}));
                                                        						
							div.adopt(next);				
						}
						$self.controls.adopt(div);				
					}				
				}
			}).send();
				
			$self.startTimer();
	},
	startTimer: function() {
		myTimer = new Timer($self.delay);
		if (location.href.indexOf("?paused") < 0)
			myTimer.start();
		myTimer.register(function() {
			$self.next();		
		});
		myTimer.check();
		
		// stop timer when mouse is in the carousel
		$self.carousel.addEvent('mouseenter', function() {
			myTimer.stop();					
		});
		// start it again when it leaves
		$self.carousel.addEvent('mouseleave', function() {
			myTimer.reset();
			myTimer.start();
		});		
	}
}); // end of Carousel class

var Timer = new Class({
    options:  {
    	name: "timer for auxiliary functions",
		startTime: 0,
		stopped: true
    },
	Extends: AAIIjs,
    initialize: function(delay, options){
    	this.parent(options);	
		this.startTime = 'hello';
		this.stopped = true;
		this.delay = delay;
		TimerThis = this;
	},
	reset: function() {
		startTime = $time();
	},
	start: function() {
		startTime = $time();
		this.stopped = false;
	},
	register: function(fn) {
		TimerThis.fn = fn;
	},
	get: function() {
		if (!TimerThis.stopped) {
			return ($time()-startTime);
		}
	},
	stop: function() {
		this.stopped = true;
	},
	check: function() {
			(function() {
				if (!TimerThis.stopped) {				
				TimerThis.fn();
				}	
				TimerThis.check(); // recursive, sets off infinite loop!
				
			}).delay(TimerThis.delay);
				
	}
});

var SBox = new Class({
	options: {},
	initialize: function() {
		Shadowbox.init({
			skipSetup : true,
			players: ["html"]
		});
		this.close = 	"<div class='shadowbox-close'>" +
					 	"<button onclick='Shadowbox.close()'>Close this window</button>"+
					 	"</div><!-- shadowbox close -->";
		Class_SBox = this;
		$each($$(".slidebelow"), function(item) { item.set("onclick", "Class_SBox.slideOpen(this)"); });
	},
	openWithElement: function(el) {
		Shadowbox.open({
			content: el.title+this.close,
			title: el.get('html'),
			player: "html",			
			width: 300
		});
	},
	slideBelow: function(el) {
		// go up tree until we find a .slideTarget element (2 levels)
		if ($chk(el.getParent(".slideTarget"))) {
			el.addEvent('click', function() { // do new slide
				Class_SBox.slideOpen(el);
			});		
			return true;
		}
		return false;
	},
	slideOpen: function(el) {
	if ($chk($("slide_below"))) { 
		$("slide_below").nix();
		t = el.getChildren('span.stored')[0];
		el.set('html' ,t.get('html'));
		return false;
	}
	
		p = el.getParent(".slideTarget");
		el.set('html', "<span style='display: none' class='stored'>" + el.get('html') + "</span>Close [X]");
		d = el.getParent(".slideTarget").clone();
		d.set('style', '');

		d.setStyle('display','none');
		d.set('id', 'slide_below');
		p.grab(d, "after");
		d.set('html',el.title);
		d.reveal();
	}
});

var Shelf = new Class({
    options:  {
    	name: "scroller for homepage and other areas (shelf)",
		number: 4,
		target: 'shelf',
		stopped: false,
		url: '',
		displayed: 0
    },
	Extends: AAIIjs,
    initialize: function(options){
    	this.parent(options);
		$self = this;
		window.Shelf = this;
		$self.rightInvisible = [];
		$self.leftInvisible = [];		
	},
	start: function(options) {
		$self.target = $(options.target);
		$self.number = options.number;
		$self.url = options.url;		
		$self.itemCounter = 0;
		$self.lock = false;
		container = new Element('div', {
			'class' : 'shelf'
		});
		$self.target.adopt(container);
		
		// two arrows
		var left = new Element('a', {
			'class' : 'shelf_leftarrow',
			'styles' : {
				'display' : 'none'
			},
			'href' : 'javascript:void(0);',
			'events' : {
				'click' : function() {
					$self.slidePrev();
				}
			}
		});		
		var right = new Element('a', {
			'class' : 'shelf_rightarrow',
			'styles' : {
				'display' : 'none'
			},
			'href' : 'javascript:void(0);',
			'events' : {
				'click' : function() {
					$self.slideNext();
				}
			}			
		});
		var counter = new Element('div', {
			'id' : 'shelf_counter'
		});
		$self.target.adopt(counter);		
		$self.target.adopt(left);
		$self.target.adopt(right);
		// make request
		
		// index of item array to start at
		start = 0;		
		
		var req = new Request.JSON({url: $self.url,
			method: 'get',
			onRequest: function() {
				container.set('text', 'loading...');
			},
			onSuccess: function(theJSON) {
				// hide throbber
				container.set({'styles':{'backgroundImage':'none'}});
				// clear whatever may be in there
				container.empty();			
				
				// reveal the arrows
				right.show();
				left.show();
				i = 0;
				while ($chk(theJSON.items[i])) {
					window.Shelf.createItem(theJSON.items[i], container);
					i++;		
				}
			}
		}).send();
		
		// set up variables for fading
		switch ($self.number) {
			case 3:
				difference = 190;
			break;
			default:
				difference = 190;
		}			
	},
	createItem: function(JSONarray, container) {
			$self.itemCounter++;
			// create elements
			var div = new Element('div', {
				'class' : 'shelf_item shelf_columns_'+$self.number,
				'id' : 'shelf_item_'+$self.itemCounter
			});
			var div2 = new Element('div', {
				'class' : 'inner'
			});		
			var span = new Element('span', {
				'html' : JSONarray.category,
				'class' : 'category'
			});
			var img = new Element('img', {
				'src' : JSONarray.image
			});
			var a = new Element('a', {
				'href' : JSONarray.link,
				'class' : 'shelf_imglink'
			});		
			div2.adopt(span);
			div2.adopt(img);
			a.wraps(img);
			div.adopt(div2);
			div.addEvents({
				'mouseover' : function() {
					temp = this.getFirst().getFirst().get('text');
					this.getFirst().getFirst().set('text', 'click to read journal');

				},
				'mouseout' : function() {
					this.getFirst().getFirst().set('text', temp);
				}				
			});
		if ($self.itemCounter < $self.number+1 ) 
		{
			container.adopt(div); // actually put it in container, give it a home
			var divf = new Fx.Tween(div,{property: 'opacity'});
			divf.start(1);
			$self.lastItem = $self.itemCounter;
			div.set('class', 'shelf_item shelf_columns_'+$self.number+' shelf_pos_'+$self.itemCounter);
			div.setStyles({
				'position': 'absolute',
				'top': '20px'
			});
			div.setStyle('left', ((difference*($self.itemCounter-1)+27)));
		}
			else
		{ 
			// hide the item off to the side, we're not displaying it yet.	
			container.adopt(div);
			$self.rightInvisible.push(div);
			div.setStyles({
				'position':'static',
				'visibility':'hidden'
			});
		}
		$self.updateTotals();
	},
	slideNext: function() {
		if (!$chk($self.rightInvisible[0])) {
			$self.fakeMoveRight();
			return false;
		} else if ($self.lock) {
			return false;
		}
		// this is incompatible with numbers other than 3
			left = $$('.shelf_pos_1')[0];
			middle = $$('.shelf_pos_2')[0];		
			right = $$('.shelf_pos_3')[0];
			
			var Q = new Queue(
				// step 1: move all to the left.
				function() { 		
					$self.lock = true; // lock so no more clicks start animation				
					$self.moveLeft(left, function() {
						$self.moveLeft(middle, function() {
							$self.moveLeft(right, function() {						// callback
									Q.callChain(); // call next function in this chain
								});			
							});
						}
					);
					
					
				},
				// step 2: hide the leftmost image and add to leftInvisible array.
				function() {
					// HIDE leftmost
					left.setStyles({
						'position': 'static',
						'visibility' : 'hidden'
					});
					$self.leftInvisible.unshift(left);					
					
					// reset CSS Classes
					left.removeClass('shelf_pos_1');
					middle.removeClass('shelf_pos_2');					
					right.removeClass('shelf_pos_3');
					
					left = middle;
					middle = right;
					
					left.addClass('shelf_pos_1'); // middle = new 'left'
					middle.addClass('shelf_pos_2'); // right = new 'middle'
					
					// new 'right' is displayed now:					
					// DISPLAY next
					var div = $self.rightInvisible[0];
					div.addClass('shelf_pos_3');
					div.setStyles({
						'position': 'absolute',
						'top': '20px'
					});
					div.setStyle('left', 402+difference); // queue up					
					right = div;
					Q.callChain();

				},
				// step 3: create the next right image and clear div from $self.rightInvisible
				function() {
					$self.lock = false; // unlock		
					right = $$('.shelf_pos_3')[0];				
					$self.moveLeft(right);
					$self.rightInvisible.shift();
					$self.updateTotals();
				}
			);
			Q.callChain(); // starts first function in chain
						   // the rest are called from within
	},
	slidePrev: function() {
		if (!$chk($self.leftInvisible[0])) {
			$self.fakeMoveLeft();
			return false;
		} else if ($self.lock) {
			return false;
		}
	
		// this is incompatible with numbers other than 3
			left = $$('.shelf_pos_1')[0];
			middle = $$('.shelf_pos_2')[0];		
			right = $$('.shelf_pos_3')[0];
			
			var Q = new Queue(
				// step 1: move all to the left.
				function() { 		
					$self.lock = true; // lock so no more clicks start animation
					$self.moveRight(right, function() {
						$self.moveRight(middle, function() {
							$self.moveRight(left, function() {						// callback
									Q.callChain(); // call next function in this chain
								});			
							});
						}
					);
					
					
				},
				// step 2: hide the rightmost image and add to rightInvisible array.
				function() {
					// HIDE rightmost
					right.setStyles({
						'position': 'static',
						'visibility' : 'hidden'
					});
					$self.rightInvisible.unshift(right);
					
					// reset CSS Classes
					left.removeClass('shelf_pos_1');
					middle.removeClass('shelf_pos_2');					
					right.removeClass('shelf_pos_3');
					
					right = middle;
					middle = left;
					
					right.addClass('shelf_pos_3'); // right = new 'left'
					middle.addClass('shelf_pos_2'); // right = new 'middle'
					
					// new 'left' is displayed now:					
					// DISPLAY next
					var div = $self.leftInvisible[0];
					div.addClass('shelf_pos_1');
					div.setStyles({
						'position': 'absolute',
						'top': '20px'
					});
					div.setStyle('left', 27-difference); // queue up					
					Q.callChain();
					left = div;
				},
				// step 3: create the next right image.
				function() {
					$self.lock = false; // unlock
					left= $$('.shelf_pos_1')[0];				
					$self.moveRight(left);
					$self.leftInvisible.shift();				
					$self.updateTotals();					
				}
			);
			Q.callChain(); // starts first function in chain
						   // the rest are called from within
		   
	},
	moveLeft: function(el, fn) {
			if (!$chk(fn)) { fn = $lambda(true); } // set up callback function
			var fx = new Fx.Morph(el, {
				duration: 50, 
				transition: 'sine:in:out',
				onStart: function() {
					el.set('opacity', .5);
				},
				onComplete: function() {
					el.set('opacity', 1);				
					fn();
				}
			});
			fx.start({
				'left' : (el.getPosition(container).x)-difference
			});
	},
	moveRight: function(el, fn) {
			if (!$chk(fn)) { fn = $lambda(true); } // set up callback function
			var fx = new Fx.Morph(el, {
				duration:50, 
				transition: 'sine:in:out',
				onStart: function() {
					el.set('opacity', .5);
				},
				onComplete: function() {
					el.set('opacity', 1);				
					fn();
				}
			});
			fx.start({
				'left' : (el.getPosition(container).x)+difference
			});
	},
	fakeMoveLeft: function() {
		// bounce 'em to the left
		var arr = [$$('.shelf_pos_1')[0], $$('.shelf_pos_2')[0], $$('.shelf_pos_3')[0]];
		$each(arr, function(el) {
			var fx = new Fx.Morph(el, {
				duration: 50,
				onComplete: function() {
					var fx2 = new Fx.Morph(el, {'duration':50});
					fx2.start({'left': el.getPosition(container).x+10});
				}
			});
			fx.start({'left': el.getPosition(container).x-10});
		});
	},
	fakeMoveRight: function() {
		// bounce 'em to the left
		var arr = [$$('.shelf_pos_1')[0], $$('.shelf_pos_2')[0], $$('.shelf_pos_3')[0]];
		$each(arr, function(el) {
			var fx = new Fx.Morph(el, {
				duration: 50,
				onComplete: function() {
					var fx2 = new Fx.Morph(el, {'duration':50});
					fx2.start({'left': el.getPosition(container).x-10});
				}
			});
			fx.start({'left': el.getPosition(container).x+10});
		});
	},
	updateTotals: function() {
		var lcount = 0;
		var rcount = 0;	
		var text = "<img src='/beta/images/shelf/on.gif' />";
		$each($self.leftInvisible, function() {
			lcount++;
			text = "<img src='/beta/images/shelf/off.gif' />" + text;			
		});
		$each($self.rightInvisible, function() {
			rcount++;
			text = text + "<img src='/beta/images/shelf/off.gif' />";			
		});
		$('shelf_counter').set('html', text);
	}
});
	
	/************************************************
	 |    Custom Utility Classes					|
	 |	  > Queue, etc.								| 	 
	 ***********************************************/
	 
		Queue = new Class({
	    	    Implements: Chain,
		        initialize: function(){
	            this.chain.apply(this, arguments);
	        	}
    		});
		Util = new Class({
				initialize: function(){
				
				},
				getFileExtension: function(inputstr) 
					{ 
					 if( inputstr.length == 0 ) return "";
					 
					 var dot = inputstr.lastIndexOf("."); 
					 if( dot == -1 ) return ""; 
					 var extension = inputstr.substr(dot,inputstr.length); 
					 return extension; 
				},
				emptyChain: function(chain) {
					while (chain.callChain()) {}
					return true;
				}
		});
        
Scrollerize = new Class({
  initialize: function(el, columns) {
    // arrows
	this.self = this;
    this.container = el;
    this.columns = columns;
    this.itemWidth = el.getChildren('li')[0].getStyle('width').replace(/px/gi, "");
    this.itemWidth = parseInt(this.itemWidth);
    this.oneColumnWidth = (this.itemWidth + 10) * columns;
    this.currentScroll = {x: 0, y: 0};
    this.numItems = el.getChildren('li').length;
    
    this.wrap = new Element('div', {"class":"scroller-wrap"});
    this.uberWrap = new Element('div', {"class" : "scroller-uberwrap"});
    this.uberWrap.adopt(this.wrap);
    
    this.container.grab(this.uberWrap, "before");
    this.wrap.grab(this.container);
    this.uberWrap.grab(this.wrap); 
    
  
    
    var leftArr = new Element('a', {
      "class" : "scroller-arrow left",
      html: 'Scroll Left',
      href: "#page-1",      
      events: {
        'click' : (function() {
          this.left();
          }).bind(this)
      }
    });
    var rightArr = new Element('a', {
      "class" : "scroller-arrow right",
      html: 'Scroll Right',
      href: "#page-2",
      events: {
        'click' : (function() {
          this.right();
          }).bind(this)
      }
    });
    
    this.leftArrow = leftArr;
    this.rightArrow = rightArr;
    this.leftArrow.setStyle('opacity', 0);

    // styles
    this.uberWrap.adopt(leftArr, rightArr);
    
    var myfx = new Fx.Scroll(this.wrap);
    myfx.set(0,0);
  },
  left: function() {
    var myfx = new Fx.Scroll(this.wrap);
    this.currentScroll.x -= this.itemWidth;
    this.currentScroll.y = this.currentScroll.y;
    this.self.checkArrows("left");
    myfx.start(this.currentScroll.x, this.currentScroll.y);    
  },
  right: function() {
    var myfx = new Fx.Scroll(this.wrap);
    this.currentScroll.x += this.itemWidth;
    this.currentScroll.y = this.currentScroll.y;
    this.self.checkArrows("right");    
    myfx.start(this.currentScroll.x, this.currentScroll.y);
  },
  checkArrows: function(direction) {
    this.leftArrow.fade(1);
    this.rightArrow.fade(1);
    if (this.columns != 1) {
        if (direction == "right") {
          if (this.currentScroll.x >= (this.oneColumnWidth * this.columns - this.oneColumnWidth)) {
            this.currentScroll.x = (this.oneColumnWidth * this.columns) - (this.oneColumnWidth);
            this.rightArrow.fade(0);
          }
        } else {
          if (this.currentScroll.x <= 0) { 
            this.currentScroll.x = 0;
            this.leftArrow.fade(0);
          }      
        }
    } else {
    	if (direction == "left" && this.currentScroll.x == 0) {
        	this.leftArrow.fade(0);
        } else if (direction == "right" && this.currentScroll.x == (this.itemWidth * this.numItems - this.itemWidth)) {
        	this.rightArrow.fade(0);
        }
    }
  }
});

/* Comment-form */
var CommentForm = function() {
	var state = $("comment-state");
	var name = $("comment-name");
	var req = new Request.JSON({
		url: '/users/commentInfo',
		mode: 'get',
		onRequest: function() {
			state.disabled = name.disabled = 1;
			state.value = name.value = "Loading...";
		},
		onSuccess: function(r) {
			state.disabled = name.disabled = 0;
			if ($chk(r.name) && $chk(r.state)) {
				state.value = r.state;
				name.value = r.name;
			}
		},
		onFailure: function() {
			state.disabled = name.disabled = 0;
			state.value = name.value = "";
		}
	}).send();
}

/* sharepops */
var Sharepops = function() {
	$each($$(".share-pop"), function(i) {
		i.addEvent('click', function(e) {
			var sizestr = "width=600,height=325";
			if (i.hasClass('big')) {
				sizestr = "width=860,height=500";
			}
			window.open(i.get('href'), "Share using " + i.get('text'), "status=1,toolbar=0,location=0,menubar=1,scrollbars=1,"+sizestr);
			return false;
		});
	});
};

/*
---
description:     ScrollSpy

authors:
  - David Walsh (http://davidwalsh.name)

license:
  - MIT-style license

requires:
  core/1.2.1:   '*'

provides:
  - ScrollSpy
...
*/
var ScrollSpy=new Class({Implements:[Options,Events],options:{container:window,max:0,min:0,mode:"vertical"},initialize:function(a){this.setOptions(a);this.container=document.id(this.options.container);this.enters=this.leaves=0;this.max=this.options.max;this.inside=false;this.addListener();},addListener:function(){this.container.addEvent("scroll",function(c){var a=this.container.getScroll(),b=a[this.options.mode=="vertical"?"y":"x"];if(b>=this.options.min&&(this.max==0||b<=this.max)){if(!this.inside){this.inside=true;this.enters++;this.fireEvent("enter",[a,this.enters,c]);}this.fireEvent("tick",[a,this.inside,this.enters,this.leaves,c]);}else{if(this.inside){this.inside=false;this.leaves++;this.fireEvent("leave",[a,this.leaves,c]);}}this.fireEvent("scroll",[a,this.inside,this.enters,this.leaves,c]);}.bind(this));}});
