PageSet = new Class({
	initialize: function(pageset_element, pod, box)
	{
		this.element = pageset_element;
		this.isScrolling = false;
		
		this.scrollCallback = null;
		
		this.page_buffer = new Element('div', {'class':'data'});
		
		this.pod = pod;

		this.initPages();
		this.current_page = this.page[0];
		
		this.direction = 1;
		
		if(this.pod)
		{
			this.initHorizontalMode(this.pod.inner_box);
			this.pod.setTitle(this.current_page.title);
			this.box = this.pod.inner_box;
		}
		
		if(box)
		{
			this.box = box;
			this.initHorizontalMode(this.box);
		}

		this.initScrollEffect();
		
		var nav_element = this.element.getElement('.nav').innerHTML;
		if(nav_element != "")
		{
			this.nav = $(nav_element);
			this.buildNav();
		}
	},
	
	newPage: function(o)
	{
		// Create The Page Element
		var div = new Element('div', {'class':'page'});
		var number = this.page.length;
		
		div.setStyle('height', this.current_page.element.getCoordinates().height);
		
		var npage = new Page(div, this, number, o);
		this.page[number] = npage;
		
		npage.next_page = this.current_page.next_page;
		npage.prev_page = this.current_page;
		
		if(this.current_page.next_page)
		{
			this.current_page.next_page.prev_page = npage;
		}
		this.current_page.next_page = npage;
		
		
		
		// Add the page to the document.
		div.injectAfter(this.current_page.element);
		
		// Reset the scroll container width.
		this.initHorizontalMode(this.box);
	},
	
	next: function()
	{
		this.current_page.next();
		return this.current_page.number;
	},
	
	back: function()
	{
		this.current_page.back();
		return this.current_page.number;
	},
	
	onFirst: function()
	{
		return this.current_page.prev_page == null;
	},
	
	onLast: function()
	{
		return this.current_page.next_page == null;
	},
	
	goTo: function(number)
	{
		this.page[number].scrollTo();
	},
	
	initHorizontalMode: function (scroll_container)
	{
		// Get the width of the scroll container in pixels.
		// we don't know this because it is currently
		// set to a % in CSS.
		var scroll_container_width = scroll_container.getCoordinates().width;
		
		// IE and Safari don't agree with Firefox that 100% width plus overflow: hidden
		// work together so we convert the width from percent to pixels. :P
		// but not for firefox... that causes a hight issue.
		//if(!window.gecko)
		//{
			scroll_container.setStyle('width', scroll_container_width);
		//}
		
		// Not needed for verticle scroll.
		var scroll_frames = $$('.scroll_frame');
		
		this.element.setStyle('width', scroll_container_width * (this.page.length));
		
		this.page.forEach(function(item, i){
			item.element.setStyle('width', scroll_container_width);
		});
	},
	
	buildNav: function()
	{
		for(var i = 0; i < this.page.length; i++)
		{
			if(!this.page[i].disableNav)
			{
				nav_button = new Element('tr');
				nav_button.page = this.page[i];

				nav_button.injectInside(this.nav);
				
				nav_button.page.nav_icon = new Element('td');
				nav_button.page.updateNavIcon();
				nav_button.page.nav_icon.injectInside(nav_button);
				
				nav_text = new Element('td');
				nav_text.setHTML("<a href=\"javascript:void(0);\">" + nav_button.page.navTitle + "</a>");
				nav_text.injectInside(nav_button);
				
				nav_button.addEvent('click', function(e){
					window.nobeforeunload=true;
					if(this.page.active)
					{
						this.page.scrollTo();
					}
				});
			}
		}
	},
	
	hidePage: function(id)
	{
		var page = this.getPageById(id);
		if(page != null)
		{
			page.hide();
		}
	},
	
	getPageById: function(id)
	{
		if(id != null)
		{
			for(var i = 0; i < this.page.length; i++)
			{
				if(this.page[i].id == id)
				{
					return this.page[i];
				}
			}
		}
		
		// If we get this far the page was not found.
		return null;
	},
	
	initPages: function()
	{
		// Get page elements
		var pages = this.element.getElements('.page');
		
		if(pages.length > 0)
		{
			this.page = new Array();
			for(var i = 0; i < pages.length; i++)
			{
				this.page[i] = new Page(pages[i], this, i);
				
				this.page[i].next_page = null;
				
				if(i > 0)
				{
					this.page[i].prev_page = this.page[i-1];
					this.page[i].prev_page.next_page = this.page[i];
				}
				else
				{
					this.page[i].prev_page = null;
				}
			}
		}
	},
	
	removeScrollBars: function ()
	{
		// This is to resolve an issue witnessed in firefox where
		// browser rendered scroll bars cause tearing while
		// the pageset is scrolling.
		if(!this.isScrolling)
		{
			this.isScrolling = true;
			
			// Remove scrollbars on elements.
			var e = this.box.getElements('*');
			for(var i = 0; i < e.length; i++)
			{
				try
				{
					e[i].prev_overflow = e[i].getStyle('overflow');
					e[i].setStyle('overflow', 'hidden');
				}
				catch(e)
				{
					e[i].prev_overflow = null;
				}
			}
			
			// hide iframes
			e = this.box.getElements('iframe');
			for(var i = 0; i < e.length; i++)
			{
				try
				{
					e[i].prev_display = e[i].getStyle('display');
					e[i].setStyle('display', 'none');
				}
				catch(e)
				{
					e[i].prev_display = null;
				}
			}
		}
	},
	
	restoreScrollBars: function ()
	{
		// This is to resolve an issue witnessed in firefox where
		// browser rendered scroll bars cause tearing while
		// the pageset is scrolling.
		
		this.isScrolling = false;
		
		// Restore scrollbars on elements.
		var e = this.box.getElements('*');
		for(var i = 0; i < e.length; i++)
		{
			if(e[i].prev_overflow != null)
			{
				e[i].setStyle('overflow', e[i].prev_overflow);
			}
			e[i].prev_overflow = null;
		}
		
		// Restore iframes
		e = this.box.getElements('iframe');
		for(var i = 0; i < e.length; i++)
		{
			if(e[i].prev_display != null)
			{
				e[i].setStyle('display', e[i].prev_display);
			}
			e[i].prev_display = null;
		}	
	},
	
	initScrollEffect: function()
	{
		var me = this;
		var scroll_options = {
			transition: Fx.Transitions.Quad.easeInOut,
			duration: 1000,
			wheelStops: false,
			wait: false,
			onComplete: function(){
				me.restoreScrollBars();
				if(me.scrollCallback != null)
				{
					me.scrollCallback();
				}
			}
		};
		
		this.scroll_effect = new Fx.Scroll(this.box, scroll_options);
	},
	
	firstAvailablePage: function(to)
	{
		while(to != null && to.hidden)
		{
			if(this.direction > 0)
			{
				if(to.next_page != null)
				{
					to = to.next_page;
				}
				else
				{
					break;
				}
			}
			else
			{
				if(to.prev_page != null)
				{
					to = to.prev_page;
				}
				else
				{
					break;
				}
			}
		}
		
		if(to.hidden)
		{
			to = this.current_page;
		}
		
		return(to);
	},
	
	snapToCurrent: function()
	{
		var el = this.current_page.element
		this.box.scrollTo(el.offsetLeft, el.offsetTop);
	},
	
	scrollTo: function(to)
	{
		this.current_page.onNotCurrent();
		to = this.firstAvailablePage(to);
		this.current_page = to;
		this.removeScrollBars();
		this.scroll_effect.toElement(to.element);
		if(this.pod)
		{
			this.pod.setTitle(to.title);
		}
		this.current_page.onCurrent();
	}
});

Page = new Class({
	initialize: function(page_element, page_set, number, o)
	{
		this.number = number;
		this.element = page_element;
		this.hidden = false;
		
		if((o != undefined) && (o != null))
		{
			this.loadFromObject(o);
		}
		else
		{
			this.loadFromTagOutput();
		}
		
		this.page_set = page_set;
		
		this.initControls();
	},
	
	loadFromTagOutput: function()
	{
		this.id = this.element.getAttribute('id');
		this.title = this.element.getElement('.title').innerHTML;
		this.navTitle = this.element.getElement('.navTitle').innerHTML;
		this.activeIcon = this.element.getElement('.activeIcon').innerHTML;
		this.inactiveIcon = this.element.getElement('.inactiveIcon').innerHTML;
		this.disableNav = (this.element.getElement('.disableNav').innerHTML == "true");
		eval("this.onCurrent = function(){" + this.element.getElement('.onCurrent').innerHTML + "};");
		eval("this.onNotCurrent = function(){" + this.element.getElement('.onNotCurrent').innerHTML + "};");
		
		this.setActive(this.element.getElement('.active').innerHTML == "true");
	},
	
	loadFromObject: function(o)
	{
		this.id = o.id;
		this.title = o.title;
		this.navTitle = o.navTitle;
		this.activeIcon = o.activeIcon;
		this.inactiveIcon = o.inactiveIcon;
		this.disableNav = o.disableNav;
		if(o.onCurrent)
		{
			this.onCurrent = o.onCurrent;
		}
		if(o.onNotCurrent)
		{
			this.onNotCurrent = o.onNotCurrent;
		}
		
		this.setActive(o.active);
	},
	
	updateNavIcon: function()
	{
		if(!this.disableNav)
		{
			this.nav_icon.setHTML("<img src=\"" + this.icon + "\">");
		}
	},
	
	setActive: function(active)
	{
		this.active = active;
		if(this.active)
		{
			this.icon = this.activeIcon;		
		}
		else
		{
			this.icon = this.inactiveIcon;
		}	
	},
	
	initControls: function()
	{
		var next_controls = this.element.getElements('.next');
		var back_controls = this.element.getElements('.back');
		
		for(var i = 0; i < next_controls.length; i++)
		{
			next_controls[i].page_object = this;
			next_controls[i].addEvent('click', function(e){
				e = new Event(e).stop();
				e.target.page_object.next();
			});
		}
		
		for(i = 0; i < back_controls.length; i++)
		{
			back_controls[i].page_object = this;
			back_controls[i].addEvent('click', function(e){
				e = new Event(e).stop();
				e.target.page_object.back();
			});
		}
	},
	
	onCurrent: function()
	{
		// Event to fire when page becomes the current page.
	},
	
	onNotCurrent: function()
	{
		// Event to fire when page is no longer the current page.
	},
	
	scrollTo: function()
	{
		this.page_set.direction = 1;
		this.page_set.scrollTo(this);
	},
	
	hide: function()
	{
		if(!this.hidden)
		{
			this.old_diaplay = this.element.getStyle('display');
			this.element.setStyle('display', 'none');
			this.hidden = true;
			
			this.page_set.snapToCurrent();
		}
	},
	
	show: function()
	{
		if(this.hidden)
		{
			this.element.setStyle('display', this.old_diaplay);
			this.hidden = false;
			
			this.page_set.snapToCurrent();
		}
	},
	
	next: function ()
	{
		if(this.next_page)
		{
			this.page_set.direction = 1;
			this.page_set.scrollTo(this.next_page);
		}
	},
	
	back: function ()
	{
		if(this.prev_page)
		{
			this.page_set.direction = -1;
			this.page_set.scrollTo(this.prev_page);
		}
	}
});

WizardControls = new Class({
	initialize: function(page_set)
	{
		this.page_set = page_set;
		
		// Create the wizard control area.
		this.buildControlArea();
	},
	
	buildControlArea: function()
	{
		this.control_box = new Element('div', {'class':'wizard_bar'});
		this.control_box.injectAfter(this.page_set.pod.inner_box);
		
		this.previous_control = new Element('div', {'styles':{'float': 'left'}});
		this.previous_control.injectInside(this.control_box);
		
		this.previous_button = new Element('input', {'type': 'button', 'class':'wizard_button', 'value':'<< Previous'});
		this.previous_button.injectInside(this.previous_control);
		
		this.advance_control = new Element('div', {'styles':{'float': 'right'}});
		this.advance_control.injectInside(this.control_box);
		
		this.next_button = new Element('input', {'type': 'button', 'class':'wizard_button', 'value':'Next >>'});
		this.next_button.injectInside(this.advance_control);
	},
	
	hide: function()
	{
		this.control_box.setStyle('visibility', 'hidden');
	},
	
	show: function()
	{
		this.control_box.setStyle('visibility', 'visible');
	}
	
});