/*
$Date: 2007-06-13 22:57:31 $
$Revision: 1.2 $
*/

var CNETGallery = {};

CNETGallery.Slide = new Class({
	layout: false,
	data: null,
	slideHeight: false,

	options: {
		photoFrame: null,
		swapDuration: 500
	},

	initialize: function(slideId, siteInfo, options) {
		this.setOptions(this.options, options);
		this.slideId = slideId;
		new Ajax(this.genUrl(this.slideId, siteInfo), {
			method: 'get',
			onComplete: this.loadData.bind(this)
		}).request();
	},
	
	loadData: function(rtext) {
		this.data = eval("("+rtext+")");
		this.layout = $("slide_"+this.data.contentId) || this.createSlideLayout();
		this.slideHeight = this.layout.offsetHeight;
	},

	genUrl: function(slideId,siteData) {
		var url = siteData.pageType+"-"+siteData.nodeId+"-"+slideId+".html";
		var data = "slideid="+slideId;
		data += "&_siteid_="+siteData.siteId;
		data += "&_editionid_="+siteData.editionId;
		data += "&"+new Date().getTime();
		return url+"?"+data;
	}, 

	createSlideLayout: function() {
		var newLayout = new Element('div');
		newLayout.setAttribute("id","slide_"+this.data.contentId);
		newLayout.addClass(this.options.slideClassName);
		newLayout.setOpacity(0);
		newLayout.innerHTML = simpleTemplateParser.parseTemplate($(this.options.slideTemplate).innerHTML,this.data);
		$(this.options.photoFrame).adopt(newLayout);
		
		return newLayout;
	},

	hide: function() {
		this.layout.effect('opacity', {
			duration: this.options.swapDuration
		}).start(0);
	},

	show: function() {
		if (this.data == null) {
			this.show.delay(50,this);
			return;
		}
		this.layout.effect('opacity', {
			duration: this.options.swapDuration
		}).start(.99);

	}
});
CNETGallery.Slide.implement(new Options);

CNETGallery.Presentation = new Class({
	slideData: [],
	currentSlide: 0,
	options: {
		useAjax: true,
		getSlideIds: Class.empty,
		initialSlide: 0,
		siteData: {
			siteId: null,
			pageType: 4328,
			nodeId: null,
			editionId: 3
		},
		frameData: {
			photoFrame: null,
			currentIndicator: null,
			totalIndicator: null,
			nextButton: null,
			prevButton: null,
			swapDuration: 500,
			slideTemplate: null,
			slideClassName: 'slide'
		}
	},
	
	initialize: function(options) {
		this.setOptions(options);
		var slideIds = [];
		if ($type(options.getSlideIds) == 'array')
			slideIds = options.getSlideIds;
		else if ($type(options.getSlideIds) == 'function')
			slideIds = options.getSlideIds();
		else {
			throw ("Slide ids have not been provided, and no method of retrieving them has been established.")
			return;
		}
		this.getSlideData(slideIds);
		dbug.log("initial slide: %s", this.options.initialSlide);
		this.currentSlide = this.options.initialSlide;
		this.updateCurrentSlide(this.currentSlide);
		$(this.options.frameData.totalIndicator).innerHTML = this.slideData.length;
		$(this.options.frameData.nextButton).href = "javascript:void(0)";
		$(this.options.frameData.nextButton).addEvent('click', function() {
			this.moveSlide("next");
			return false;
		}.bind(this));
		$(this.options.frameData.prevButton).href = "javascript:void(0)";
		$(this.options.frameData.prevButton).addEvent('click', function() {
			this.moveSlide("previous");
			return false;
		}.bind(this));
		this.slideData[this.currentSlide].show();
	},

	swapSlide: function(index) {
		var frameHeight = $(this.options.frameData.photoFrame).offsetHeight;
		var slideHeight = this.slideData[index].slideHeight || this.slideData[index].layout.offsetHeight;
		if (frameHeight < slideHeight) {
			$(this.options.frameData.photoFrame).effect('height', {
				duration: this.options.frameData.swapDuration*1.5
			}).start(slideHeight);
		}

		this.slideData[this.currentSlide].hide();
		this.updateCurrentSlide(index);
		(function(){this.slideData[index].show();}).delay(this.options.frameData.swapDuration, this);
	},
	
	updateCurrentSlide: function(index) {
		this.currentSlide = index;
		$(this.options.frameData.currentIndicator).innerHTML = index+1;
	},
	
	moveSlide: function(dir) {
		var goTo = (dir == "previous") ? ((this.currentSlide == 0) ? this.slideData.length-1 : this.currentSlide - 1) : ((this.currentSlide == this.slideData.length-1) ? 0 : this.currentSlide + 1);
		this.swapSlide(goTo);
	},
	
	getSlideData: function(slideIds) {
		$each(slideIds, function(anId) {
			this.slideData.push(new CNETGallery.Slide(anId, this.options.siteData, {
				photoFrame: this.options.frameData.photoFrame,
				swapDuration: this.options.frameData.swapDuration,
				slideClassName: this.options.frameData.slideClassName,
				slideTemplate: this.options.frameData.slideTemplate
			}));
		}.bind(this));
	}
});
CNETGallery.Presentation.implement(new Options);




/*	Script: simple.template.parser.js
		Provides functionality for very simple template parsing; for more complex template parsing, use TrimPath's excellent Javascript Templates (JST): http://trimpath.com/project/wiki/JavaScriptTemplates.

		Dependencies:
		Moo - <Moo.js>, <Utility.js>, <Function.js>, <String.js>
	
		Author:
		Aaron Newton (aaron [dot] newton [at] cnet [dot] com)
		
		Object: simpleTemplateParser
		This object provides functionality for very simple template parsing; for more complex template parsing, use TrimPath's excellent Javascript Templates (JST): http://trimpath.com/project/wiki/JavaScriptTemplates. It can be used on its own or implemented into a class.
	*/

var simpleTemplateParser = {
		STP: {},
/*	Property: parseTemplate
		Parses a template with the values of an object, substituting those values for all instances of the keys in the object found within the template.

		Arguments: 
		template - a string to parse
		object - the object with your key/value pairs
		regexOptions - the options for the regex replace; defaults to 'ig' (ignore case, global replace)
		wrappers - an object with the before and after strings that are on either side of your keys (see example);
			defaults to {before: "%", after: "%"}

		Example:
(start code)
<textarea id="myTemplate">
	<p>This is some html that lets me subsitute things.</p>
	<ul>
		<li>%firstThing%</li>
		<li>%secondThing%</li>
		<li>%thirdThing%</li>
	</ul>
</textarea>
<script>
	var myTemplate = $('myTemplate').innerHTML;
	var myObject = {
		firstThing: 'hi there',
		secondThing: 'howzit goin?',
		thirdThing: 'really? me too!'
	}
	var parsed = simpleTemplateParser.parseTemplate(myTemplate, myObject);
</script>(end)
	*/
		parseTemplate: function(template, object, regexOptions, wrappers) {
			var STP = this.STP;
			STP.template = template;
			STP.object = object;
			STP.regexOptions = $pick(regexOptions, 'ig');
			STP.wrappers = $pick(wrappers, {before:'%', after:'%'});
			return STP.result = this.runParser(STP.object, STP.template, STP.regexOptions);
		},
		runParser: function(object, string, regexOptions){
			for(value in object){
				switch($type(object[value])){
					case 'string':
						string = this.tmplSubst(value, object[value], string, regexOptions);
						break;
					case 'number':
						string = this.tmplSubst(value, object[value], string, regexOptions);
						break;
					case 'object':
						string = this.runParser(object[value]);
						break;
					case 'array':
						string = this.tmplSubst(value, object[value].toString(), string, regexOptions);
						break;
				}
			}
			return string;
		},
		tmplSubst: function(key, value, string, regexOptions){
			return string.replaceAll(this.STP.wrappers.before+key+this.STP.wrappers.after, value, regexOptions);
		}
	};
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/flatfile/html/rb/js/crave/craveSlideShow.js,v $
$Log: not supported by cvs2svn $
Revision 1.1  2007/06/11 21:30:00  andyl
Adding a new slide show routine for Crave Ajax ads test. Includes additional bits from the framework

Revision 1.3  2007/03/02 01:32:52  newtona
swapped out string.replace with string.replaceAll

Revision 1.2  2007/01/26 05:56:03  newtona
syntax update for mootools 1.0
docs update

Revision 1.1  2007/01/09 02:39:35  newtona
renamed addons directory to "common" directory

Revision 1.2  2007/01/09 01:25:47  newtona
docs syntax fix

Revision 1.1  2007/01/05 18:55:02  newtona
first check in


*/
/*
Script: Fx.CSS.js
	Css parsing class for effects. Required by <Fx.Style>, <Fx.Styles>, <Fx.Elements>. No documentation needed, as its used internally.

Authors:
	- Christophe Beyls, <http://www.digitalia.be>
	- Valerio Proietti, <http://mad4milk.net>

License:
	MIT-style license.
*/

Fx.CSS = {

	select: function(property, to){
		if (property.test(/color/i)) return this.Color;
		if (to.test && to.test(' ')) return this.Multi;
		return this.Single;
	},

	parse: function(el, property, fromTo){
		if (!fromTo.push) fromTo = [fromTo];
		var from = fromTo[0], to = fromTo[1];
		if (!to && to != 0){
			to = from;
			from = el.getStyle(property);
		}
		var css = this.select(property, to);
		return {from: css.parse(from), to: css.parse(to), css: css};
	}

};

Fx.CSS.Single = {

	parse: function(value){
		return parseFloat(value);
	},

	getNow: function(from, to, fx){
		return fx.compute(from, to);
	},

	getValue: function(value, unit){
		return value+unit;
	}

};

Fx.CSS.Multi = {

	parse: function(value){
		return value.push ? value : value.split(' ').map(function(v){
			return parseFloat(v);
		});
	},

	getNow: function(from, to, fx){
		var now = [];
		for (var i = 0; i < from.length; i++) now[i] = fx.compute(from[i], to[i]);
		return now;
	},

	getValue: function(value, unit){
		return value.join(unit+' ')+unit;
	}

};

Fx.CSS.Color = {

	parse: function(value){
		return value.push ? value : value.hexToRgb(true);
	},

	getNow: function(from, to, fx){
		var now = [];
		for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i]));
		return now;
	},

	getValue: function(value){
		return 'rgb('+value.join(',')+')';
	}

};

/*
Script: Fx.Style.js
	Contains <Fx.Style>

Author:
	Valerio Proietti, <http://mad4milk.net>

License:
	MIT-style license.
*/

/*
Class: Fx.Style
	The Style effect; Extends <Fx.Base>, inherits all its properties. Used to transition any css property from one value to another. Includes colors.
	Colors must be in hex format.

Arguments:
	el - the $(element) to apply the style transition to
	property - the property to transition
	options - the Fx.Base options (see: <Fx.Base>)

Example:
	>var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
	>marginChange.start(10, 100);
*/

Fx.Style = Fx.Base.extend({

	initialize: function(el, property, options){
		this.element = $(el);
		this.property = property;
		this.parent(options);
	},

	/*
	Property: hide
		Same as <Fx.Base.set> (0)
	*/

	hide: function(){
		return this.set(0);
	},

	setNow: function(){
		this.now = this.css.getNow(this.from, this.to, this);
	},

	set: function(to){
		this.css = Fx.CSS.select(this.property, to);
		return this.parent(this.css.parse(to));
	},

	/*
	Property: start
		displays the transition to the value/values passed in

	Example:
		(start code)
		var var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
		marginChange.start(10); //tries to read current margin top value and goes from current to 10
		(end)
	*/

	start: function(from, to){
		if (this.timer && this.options.wait) return this;
		var parsed = Fx.CSS.parse(this.element, this.property, [from, to]);
		this.css = parsed.css;
		return this.parent(parsed.from, parsed.to);
	},

	increase: function(){
		this.element.setStyle(this.property, this.css.getValue(this.now, this.options.unit));
	}

});

/*
Class: Element
	Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
*/

Element.extend({

	/*
	Property: effect
		Applies an <Fx.Style> to the Element; This a shortcut for <Fx.Style>.

	Example:
		>var myEffect = $('myElement').effect('height', {duration: 1000, transition: Fx.Transitions.linear});
		>myEffect.start(10, 100);
	*/

	effect: function(property, options){
		return new Fx.Style(this, property, options);
	}

});
