// define some additional global variables
var isIE6 = (Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) == 6)?true:false;

// extend Prototype library by adding some new methods for Element
// define custom methods
var customMethods = {
	resizeToPage: function(element) {
		var pg = $(document.body).getDimensions(); // page height
		var vp = $(document.viewport).getDimensions(); // viewport height
		// always use the greater of the two
		//var new_w = (pg.width >= vp.width)?pg.width:vp.width;
		var new_h = (pg.height >= vp.height)?pg.height:vp.height;
		$(element).setStyle({
			//width: new_w + 'px',
			width: '100%',
			height: new_h + 'px'
		});
		return $(element);
	},
	
	resizeToViewport: function(element, margin) {
		var vp = $(document.viewport).getDimensions(); // viewport dimensions
		var less = margin*2;
		$(element).setStyle({
			width: vp.width - less + 'px',
			height: vp.height - less + 'px'
		});
		return $(element);
	},
	
	centerInViewport: function(element, animation) {
		var vp = $(document.viewport).getDimensions();
		var el = $(element).getDimensions();
		var el_left = Math.round((vp.width - el.width)/2);
		var el_top = Math.round((vp.height - el.height)/2);
		// we are assuming that the position is fixed
		// ie6 does not support 'fixed' so use absolute position instead. need to add amount of scroll down the page
		var vp_offset = $(document.viewport).getScrollOffsets();
		if (isIE6) el_top += vp_offset.top;
		
		// if there is an animation parameter then slide the object in to the center position from one of the browser edges
		// possible values are "left" and "top"
		if (animation == "left" || animation == "top") {
			if (animation == "left") {
				$(element).setStyle({
					left: -el.width + 'px',
					top: el_top + 'px'
				});
			}
			if (animation == "top") {
				$(element).setStyle({
					left: el_left + 'px',
					top: -el.height + 'px'
				});
			}
			new Effect.Move(element, {
				x: el_left,
				y: el_top,
				mode: 'absolute',
				duration: 2,
				queue: 'start'
			});
		// no animation
		} else {
			$(element).setStyle({
				left: el_left + 'px',
				top: el_top + 'px'
			});
		}
		return $(element);
	},
	
	pngFix: function(element, sizingMethod, autoResize) {
		if(isIE6 && document.body.filters) {
			if (!sizingMethod) var sizingMethod = 'scale'; // by default use 'scale', alternative methods are 'crop' and 'image'
			if (!autoResize) var autoResize = false; // by default, don't resize the png when the window resizes
			var elem = $(element);
			var e = elem.getDimensions();
			var img_src = '';
			
			if(elem.src && elem.src.include('.png')) { // check if it is an image with .png in the src
				img_src = elem.src;
				elem.setStyle({
					width: e.width + 'px',
					height: e.height + 'px',
					filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + img_src + '", sizingMethod="' + sizingMethod + '")'
				});
				elem.src = '/images/spacer.gif'; // set src to a transparent gif
			} else { // else it is a background image on an element 
				img_src = elem.getStyle('backgroundImage');// string is in the form of 'url("http://image_source_here.gif")' - need to get just the src part
				if (img_src.include('.png')) {
					img_src_arr = img_src.split("\"",2);
					img_src = img_src_arr[1];
					elem.setStyle({
						//width: e.width + 'px',
						//height: e.height + 'px',
						filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + img_src + '", sizingMethod="' + sizingMethod + '")',
						background: 'none'
					});
				}
			}
			if (img_src.include('.png')) {
				if (autoResize) {	
					Event.observe(window, 'resize', function() {
						elem.setStyle({width: '100%', filter: ''});
						var new_dimensions = elem.getDimensions();
						elem.setStyle({
							//width: new_dimensions.width + 'px',
							//height: new_dimensions.height + 'px',
							filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + img_src + '", sizingMethod="' + sizingMethod + '")'
						});
					});
				}
			} else {
				// die gracefully by doing nothing...
				//alert("trying to run png fix on a non-png file type: src=" + img_src);
			}
			// store the original src because we may need to reference it
			$(element).secret_src = img_src;
		}
		return $(element);
	},
	// checks if x,y coordinates (usually from a page click) are within bounds of element
	// x and y are integer values
	hasPosition : function(element, x, y){
        element = $(element);
        this.topleft = Element.cumulativeOffset(element);
        this.bottomright = [
            this.topleft[0] + element.offsetWidth,
            this.topleft[1] + element.offsetHeight,
        ];
        return (y >= this.topleft[1] &&
            y <  this.bottomright[1] &&
            x >= this.topleft[0] &&
            x <  this.bottomright[0]);
    },
    imgShield: function(element) {
    	this.shield = $(document.createElement('img'));
    	this.shield.src = "/images/web/spacer.gif";
    	this.shield.className = "img_shield";
    	$(element).insert({before: this.shield});
    	$(this.shield).clonePosition(element);
		return $(element);
	}
	
}
// apply custom methods
Element.addMethods(customMethods);



//////////////////////////////////////////////////////////////////////////////////

// some special classes. namespace with my initials SDG

if (!SDG) var SDG = {};



//////////////////////////////////////////////////////////////////////////////////

// LIGHTBOX CLASS
// by default, the lightbox covers the page with a semi-opaque mask, and shows a content box.
// the content for the box is copied from a pre-existing element on the page (content_src)

if (!SDG.lightbox) SDG.lightbox = {};
SDG.LIGHTBOXES = new Hash(); // global hash is an associative array of lightbox objects, indexed by content_src

SDG.lightbox = Class.create({
	initialize: function(content_src, options) {
		var LB = this;
		// use default options as base and overwrite as desired with options param
		this.options = Object.extend(Object.extend({ },this.default_options), options || { });
		this.content_src = content_src;
		
		this.status = false; // string for if open or closed
		this.times_viewed = 0;
		
		// build the html for the lightbox
		// each instantiation builds its own set of DOM elements
		this.mask = $(document.createElement('div'));
		this.mask.addClassName('page_mask').setStyle({display:'none', backgroundColor:this.options.mask_color});
		document.body.appendChild(this.mask);
		
		this.container = $(document.createElement('table'));
		this.container.cellpadding = 0;
		this.container.cellspacing = 0;
		var container_pos = (isIE6)?'absolute':'fixed';
		this.container.addClassName(this.options.class_name).setStyle({display:'block', position:container_pos, top:'-10000px', left:'-10000px', width: this.options.width+'px', height: this.options.height+'px'});
		var tableHTML = '<tr><td class="nw"></td><td class="n"></td><td class="ne"><div class="close_btn"></div></td></tr><tr><td class="w"></td><td class="center"><div class="lightbox_content" style="width:' + (this.options.width-76) + 'px; height:' + (this.options.height-76) + 'px;"></div></td><td class="e"></td></tr><tr><td class="sw"></td><td class="s"></td><td class="se"></td></tr>';
		this.container.insert(tableHTML);
		document.body.appendChild(this.container);
		
		// load the content
		this.content = this.container.down('.lightbox_content');
		
		switch (this.options.content_type) {
			// if getting static content (not an iframe)
			case 'static':
				this.content.update($(this.content_src).innerHTML);
			break;
			
			case 'iframe':
				// show loading graphic for while the iframe page loads
				this.content.update('<div style="text-align:center;"><img src="/images/icons/anim_loading_dots.gif" style="margin:auto;" /></div>');
			break;
			
			// i think this just moves an existing page object, centering it on top of the lightbox??
			case 'overlay':
				$(this.content_src).centerInViewport();
			break;
			
			// fetch a smarty partial using id
			case 'ajax':
				//var ajax_url = "?";
				//new Ajax.Request(ajax_url,
				//{
				//	method:'get',
				//	parameters: {
				//		product: 'Web',
				//		controller: 'WebAdmin',
				//		action: 'get_lightbox_content',
				//		content_id: LB.content_src,
				//		acnt: $('ACNT').getValue()
				//	},
				//	onSuccess: function(transport) {
				//		if (transport.responseText) LB.content.update(transport.responseText);
				//	},
				//	onFailure: function() {
				//		alert('The ajax request failed - was loading lightbox content.');			
				//	}
				//});
				alert('ajax version currently not supported');
				
			break;
		}
		
		
		this.close_btn = this.container.down('div.close_btn');
		this.close_btn.observe("click", function() {
			LB.close();
		});
		if (!this.options.close_btn) this.close_btn.hide();
		if (this.options.mask_click_out) {
			this.mask.observe('click', function() {
				LB.close()
			});
		}
		this.mask.resizeToPage().setOpacity(this.options.mask_opacity);
		Event.observe(window, 'resize', function() {
			LB.mask.resizeToPage();
		});
		
		if (this.options.sizing == 'full') {
			Event.observe(window, 'resize', function() {
				LB.resizeToFull();
			});
		} else {
			Event.observe(window, 'resize', function() {
				LB.container.centerInViewport();
			});
		}
		this.container.select('.close_btn, td.nw, td.n, td.ne, td.e, td.se, td.s, td.sw, td.w').invoke('pngFix');
		this.container.hide();
		
		// add the lightbox object to the global array (object)
		SDG.LIGHTBOXES.set(this.content_src, LB);
	},
	
	// default options: any of these can be passed in as parameters to override the defaults
	default_options: {
		content_type: 'static', // 'static': html on the page already, 'iframe': iframe with external page inside, 'overlay': ?? I forget, 'ajax': retrieve content by id
		class_name: 'lightbox', // css class for the content box (table) allows for alternate styling options
		sizing: 'fixed', // 'fixed': requires fixed pixel dimensions for height and width, 'full': expands to fill the viewport (use with iframe to maximize viewable area)
		width: 600, // integer value in pixels
		height: 400,
		sizing_margin: 32, // in pixels, how far from the edges of the viewport when using the 'full' sizing
		mask: true, // set to false if you don't want to use the page mask
		mask_color: '#1966aa',
		mask_opacity: 0.75,
		mask_click_out: true, // allows you to click the mask to exit
		close_btn: true, // whether to show the close button
		animation: false // when opening, slide in from the edge. Possible values of "top" and "left".
	},
	
	// used for the 'full' sizing option. Resizes the contents to fill up the space in the container
	resizeToFull: function() {
		// first set the content to as small as possible
		this.content = this.container.down('.lightbox_content');
		this.content.setStyle({width:'1px', height:'1px'});
		
		// resize the container table relative to the viewport and margin settings
		this.container.resizeToViewport(this.options.sizing_margin).centerInViewport();
		
		// set dimensions for the contents
		// ** assume that padding of center cell is consistent on all four sides
		// ** assume that outer cells will have the same heights (for top and bottom) and widths (for left and right)
		var container = this.container.getDimensions();
		var cell_width = this.container.down('td.nw').getStyle('width').replace(/px/,'');
		var cell_height = this.container.down('td.nw').getStyle('height').replace(/px/,'');
		var cc_pad = this.content.up().getStyle('padding-top').replace(/px/,'');
		
		// *** need to fix safari cause it can't find height and width values using getStyle...
		// it returns null values if the element has display set to none??
		// hacking it for now so it is always 32px
		if (Prototype.Browser.WebKit) {
			cell_width = 32;
			cell_height = 32;
		}
		
		// set content size to fill up the center cell
		this.content.setStyle({
			width: container.width - (cell_width*2) - (cc_pad*2) + 'px',
			height: container.height - (cell_height*2) - (cc_pad*2) + 'px'
		});
	},
	
	open: function() {
		this.status = true;
		this.times_viewed++;
		
		// first hide any select boxes on the page to prevent them from popping through the mask or shadow
		// is this IE6 specific?? as other browsers are discovered, add them here.
		if (isIE6) {
			$$('select').each( function(sel) {
				sel.setStyle({
					visibility:'hidden'
				});
			});
		}
		
		if (this.options.mask) this.mask.resizeToPage().show();
		this.container.show().centerInViewport(this.options.animation);
		
		if (!this.contents_loaded && this.options.content_type == 'iframe') {
			this.content.replace('<iframe class="lightbox_content" frameborder="0" src="' + this.content_src + '" scrolling="auto" style="width:' + (this.options.width-76) + 'px; height:' + (this.options.height-76) + 'px;"></iframe>');
			this.contents_loaded = true;
		}
		
		if (this.options.sizing == 'full') this.resizeToFull();
		
		if (this.options.content_type == 'overlay') {
			$(this.content_src).show().centerInViewport();
		}
	},
	
	close: function() {
		this.status = false;
		if (this.options.mask) this.mask.hide();
		this.container.hide();
		// show any select boxes on the page again
		if (isIE6) {
			$$('select').each( function(sel) {
				sel.setStyle({
					visibility:'visible'
				});
			});
		}
		if (this.options.content_type == 'overlay') {
			$(this.content_src).hide();
		}
	}

});






//////////////////////////////////////////////////////////////////////////////////

// CAROUSEL CLASS

if (!SDG.carousel) SDG.carousel = {};
SDG.CAROUSELS = new Hash(); // global hash is an associative array of CAROUSEL objects, indexed by content_src

SDG.carousel = Class.create({
	initialize: function(id, options) {
		var CAR = this;
		
		// expecting the id of the carousel container or the object itself
		this.container = $(id);
		this.id = this.container.identify(); // get id if present or generate one if missing.
		
		// use default options as base and overwrite as desired with options param
		this.options = Object.extend(Object.extend({ },this.default_options), options || { });
		
		this.is_playing = this.options.default_is_playing; // boolean status for if slide show is playing or not.
		this.play_timer = false; // used to store the periodical executer function for play
		
		this.btn_previous = this.container.down('.previous');
		this.btn_previous.observe('click', function() {
			//console.log("click previous");
			CAR.go_back();
		});
		this.btn_next = this.container.down('.next');
		this.btn_next.observe('click', function() {
			//console.log("click next");
			CAR.go_forward(true);
		});
		
		// the slider containing all the slides
		this.slider = this.container.down('.slides');
		
		// get an array of slides
		this.slides = this.container.select('.slide');
		
		// count how many there are
		this.total_slides = this.slides.size();
		
		// generate a thumbnail "dot" for each slide
		// and attach events
		
		/*
		this.container.select('#Thumbs a').each( function(thumb) {
			thumb.observe("click", function(event) {
				Event.stop(event);
				CAR.pause();
				var slide_number = thumb.id.replace(/Thumb_/,'');
				CAR.go_to_slide(slide_number);
				thumb.blur();
			});
		});
		*/
		this.current_slide_number = 1;
		this.current_slide = this.slides[this.current_slide_number - 1];
		this.slide_width = this.current_slide.getWidth(); // get width from the first slide
		
		this.slides.each( function(slide, index) {
			if (CAR.options.transition == 'fade') {
				slide.setStyle({
					display: (index == 0) ? 'block' : 'none',
					opacity: (index == 0) ? 1 : 0,
					'zIndex': (index == 0) ? 3 : 2
				});
				//console.log("slide ", index);
			}
			// else default 'move' transition: go through and position all of the slides
			else {
				slide.setStyle({
					display: 'block',
					left: (CAR.slide_width * index) + 'px'
				});
			}
		});
		
		SDG.CAROUSELS.set(this.id, CAR);
		
		if (this.options.is_auto_play) {
			this.play(); // start the carousel (after a delay?)
		}
		
	},
	
	// default options: any of these can be passed in as parameters to override the defaults
	default_options: {
		is_auto_play: true, // boolean for if slide show is playing by default
		delay: 10, // integer for how long to wait (in seconds) before moving to the next slide
		transition: 'move' //  possible: 'fade', or 'move'
	},
	
	play: function() {
		var CAR = this;
		this.is_playing = true;
		
		// start the periodical executer call to go_forward()
		this.play_timer = new PeriodicalExecuter( function() {
			CAR.go_forward(false); // do not reset timer when going forward
		}, CAR.options.delay);
	},
	
	pause: function() {
		this.is_playing = false;
		this.play_timer.stop();	
	},
	
	go_forward: function(is_manual) {
		var CAR = this;
		// if this is a manual request (from pressing the next button) stop and reset the timer
		if (this.is_playing && is_manual) {
			this.play_timer.stop();
			this.play();
		}
		
		//console.log("going forward");
		
		// go to the next slide
		var csn = this.current_slide_number;
		if (csn != this.total_slides) { csn++; } else { csn = 1; }
		this.go_to_slide(csn);
	},
	
	go_back: function() {
		// if playing, pause and reset it
		if (this.is_playing) {
			this.play_timer.stop();
			this.play();
		}
		
		//console.log("going back");
		
		// go back to the last slide
		var csn = this.current_slide_number;
		if (csn != 1) { csn--; } else { csn = this.total_slides; }
		this.go_to_slide(csn);
	},
	
	// called by both go_forward() and go_back()
	// allows you to jump to any slide
	go_to_slide: function(slide_number) {
		CAR = this;
		
		// check that the slide number is legit
		if (1 <= slide_number <= this.total_slides) {
			
			CAR.next_slide = this.slides[slide_number - 1];
			
			
			// do the fade transition
			if (this.options.transition == 'fade') {
				//console.log("'fade' transition");
				CAR.next_slide.setStyle({
					display: 'block',
					opacity: 0
				});
				new Effect.Parallel([
					new Effect.Opacity(CAR.current_slide, { sync: true, from: 1, to: 0 }), 
					new Effect.Opacity(CAR.next_slide, { sync: true, from: 0, to: 1 }) 
					], { 
					duration: 1,
					afterFinish: function() {
						CAR.current_slide.setStyle({ display:'none', 'zIndex': 2 });
						CAR.next_slide.setStyle({ display:'block', 'zIndex': 3 });
						
						// now set the new current slide
						CAR.current_slide_number = slide_number;
						CAR.current_slide = CAR.slides[CAR.current_slide_number - 1];
					}
				});
			}
			// default transition ("move")
			else {
				//console.log("'move' transition");
				new Effect.Move(CAR.slider, {
					x:-CAR.next_slide.getStyle('left').replace(/px/, ''), 
					y:0, 
					mode:'absolute',
					afterFinish: function() {
						// now set the new current slide
						CAR.current_slide_number = slide_number;
						CAR.current_slide = CAR.slides[CAR.current_slide_number - 1];
					}
				});
				
				
			}
			
			
			
			
			//console.log("new current slide: ", slide_number);
			
		} else {
			alert("trying to go to a slide number that doesn't exist!");
		}
	}
	
});





//////////////////////////////////////////////////////////////////////////////////

// DROP DOWN MENU CLASS

if (!SDG.drop_down_menu) SDG.drop_down_menu = {};

SDG.drop_down_menu = Class.create({
	initialize: function(nav_menu, options) {
		var DDM = this;
		
		// id of the nav menu container or the object itself
		this.nav_menu = $(nav_menu);
		//this.id = this.container.identify(); // get id if present or generate one if missing.
		
		// use default options as base and overwrite as desired with options param
		this.options = Object.extend(Object.extend({ },this.default_options), options || { });
		
		// attach events
		// loop through each li element
		this.nav_menu.select('li').each(function(parent_li) {
			
			/*
			trying to prepopulate the style ob but it's not working
			
			var submenu = parent_li.down('ul.children');
			if (submenu) {
				submenu.style.display ='none';
			}
			*/
			
			parent_li.observe("mouseenter", function() {
				DDM.open_submenu(parent_li);
			});
			
			parent_li.observe("mouseleave", function() {
				DDM.close_submenu(parent_li);
			});
			
		});
		
	},
	
	// default options: any of these can be passed in as parameters to override the defaults
	default_options: {
		//is_auto_play: true, // boolean for if slide show is playing by default
		//delay: 10, // integer for how long to wait (in seconds) before moving to the next slide
		//transition: 'move' //  possible: 'fade', or 'move'
	},
	
	open_submenu: function(parent_li) {
		var DDM = this;
		var a = $(parent_li).down('a');
		var submenu = $(parent_li).down('ul.sub-menu');
		if (submenu) {
			if (!submenu.is_open) {
				submenu.is_open = true;
				// add a class to the parent li
				a.addClassName("hover");
				// open the submenu with an animation effect
				submenu.setStyle({display:'block'});
				
				
				// ***
				// before we can use this animation stuff, we need to figure out how to write style="display:none;" inline
				// into the ul.children elements
				//Effect.BlindDown(submenu, {duration:0.33, scaleContent:false});
				//submenu.show();
			}
		}
	},
	
	close_submenu: function(parent_li) {
		var DDM = this;
		var a = $(parent_li).down('a');
		var submenu = $(parent_li).down('ul.sub-menu');
		if (submenu) {
			submenu.is_open = false;
			// add a class to the parent li
			a.removeClassName("hover");
			// open the submenu with an animation effect
			submenu.setStyle({display:'none'});
			//Effect.BlindDown(submenu, {duration:0.5});
			//submenu.hide();
		}
	}
	
});
