var ActivityCollector = new Class({
	/**
	 * constructor
	 */
	initialize: function(id,opt) {
		this.opt(id,opt); 
		if (this.opt.type == 'listing') {
			this.loadImgsListing();
		} else {
			this.loadImgs();
		}
			
		this.setup(); 
		//this.opt.onLoad(); 
	},
	/**
	 * setup class properties
	 */
	opt: function(id,opt) {
		this.els = $$(id); 
		this.opt = {
			on: {
				className: 'on',
				text: '',
				icon: uri+'img/icon_save.gif'
			},
			off: {
				className: 'off',
				text: '',
				icon: uri+'img/icon_saved.gif'
			},
			hash_name: 'uids',
			hash_ttl: 3600,
			collection: [],
			placement: 'inside',
			duration: 500,
			type: '',
			onComplete: Class.empty,
			onLoad: Class.empty,
			previousID: null
		};
		Object.extend(this.opt,opt||{});
		this.hash = new Hash.Cookie(this.opt.hash_name, {duration: this.opt.hash_ttl, path: '/', domain: '.cecentral.com'});
		this.opt.collection = (this.hash).get(this.opt.hash_name) ? (this.hash).get(this.opt.hash_name) : []; 
		this.addEvent('onComplete',this.opt.onComplete);
		this.addEvent('onLoad',this.opt.onLoad);
		this.imgs = {
			on: null,
			off: null
		}; 
	},
	/**
	 * add & remove classnames from active idx
	 * @param integer idx
	 * @param boolean inc Indicates whether idx el is part of current collection
	 */
	classNames: function(idx,inc) {
		if(!inc) {
			(this.els[idx]).removeClass(this.opt.off.className); 
			(this.els[idx]).addClass(this.opt.on.className); 
		} else {
			(this.els[idx]).removeClass(this.opt.on.className); 
			(this.els[idx]).addClass(this.opt.off.className); 
		}
	},
	/**
	 * includes this.id in current collection
	 * @return boolean
	 */
	collect: function(id) {
		this.opt.previousID = id; 
		return (this.opt.collection).include(id); 
	},
	/**
	 * checks current collection for presence of this.id
	 * @return boolean
	 */
	collected: function(id) {
		return (this.opt.collection).contains(id); 
	},
	/**
	 * returns current collection 
	 * @return array
	 */
	collection: function() {
		var arr = (this.hash).get(this.opt.hash_name); 
			/*remove any empty items*/
			arr = /*arr ? arr.remove() :*/ Array(); 
		return arr;  
	},
	
	/**
	 * setup image asset prototypes
	 */
	loadImgs: function() {
		this.imgs.on = new Asset.image(this.opt.on.icon, {id: 'iconOn', title: 'Add to your Saved Activities', alt: 'Add to your Saved Activities'});
		this.imgs.on.setOpacity(0); 
		this.imgs.on.setStyles({position: 'absolute'}); 
		this.imgs.off = new Asset.image(this.opt.off.icon, {id: 'iconOff', title: 'Remove from your Saved Activities', alt: 'Remove from your Saved Activities'});
		this.imgs.off.setOpacity(0); 
	},
	/**
	 * setup image asset prototypes
	 */
	loadImgsListing: function() {
		this.imgs.on = new Asset.image(this.opt.on.icon, {id: 'iconOn', title: 'Add to your Saved Activities', alt: 'Add to your Saved Activities'});
		this.imgs.off = new Asset.image(this.opt.off.icon, {id: 'iconOff', title: 'Remove from your Saved Activities', alt: 'Remove from your Saved Activities'});

	},
	/**
	 * @param resource el
	 * @param boolean inc Indicates whether current el is part of current collection
	 */
	insertImgs: function(el,inc) {
		switch(this.opt.placement) {
			case 'top':
				(this.imgs.off).clone().injectTop(el);
				(this.imgs.on).clone().injectTop(el);
				break; 				
			default: 
				(this.imgs.on).clone().injectInside(el);
				(this.imgs.off).clone().injectInside(el);
				break; 
		}
		if (this.opt.type == 'listing') {
			this.opacityListing(inc,el.getElements('img')); 
		} else {
			this.opacity(inc,el.getElements('img')); 
		}
		
	},
	
	/**
	 * sets up call to this.opacity
	 * @param integer idx
	 */
	toggle: function(idx) {
		var el = this.els[idx]; 
		var inc = this.collected(this.identify(el)); 
		var ref = this; 
		var imgs = el.getElements('img'); 
		if (this.opt.type == 'listing') {
			this.opacityListing(inc,imgs,true); 
		} else {
			this.opacity(inc,imgs,true); 
		}
		
	},
	
	/**
	 * toggles opacity of previously clicked el's img children
	 * @param boolean inc
	 * @param array imgs
	 * @param boolean trans
	 */
	opacity: function(inc,imgs,trans) {
		var trans = trans!=undefined ? trans : false;
		var obj = new Object(); 
		imgs.each(function(item,index){
			var on = item.getProperty('id')=='iconOn' ? true : false;
			if(trans) {
				obj[item.getProperty('id')] = item; 	
			} else { 
				item.setOpacity(!inc?(on?1:0):(on?0:1)); 
			}
		});
		if(trans) { this.trans(inc,obj); }
	},
	
	/**
	 * toggles opacity of previously clicked el's img children
	 * @param boolean inc
	 * @param array imgs
	 * @param boolean trans
	 */
	opacityListing: function(inc,imgs,trans) {
		var trans = trans!=undefined ? trans : false;
		var obj = new Object(); 
		imgs.each(function(item,index){
			
			var on = item.getProperty('id')=='iconOn' ? true : false;
			
			if(trans) {
				obj[item.getProperty('id')] = item;
			} else { 
				if(!inc) {
					if(on){
						item.setStyle('display','block');
					} else {
						item.setStyle('display','none');
					}	
				} else {
					if(on){
						item.setStyle('display','none');
					} else {
						item.setStyle('display','block');
					}	
				}				
			}			
		});
		
		if(trans) { 
			this.trans(inc,obj); 
		}
	},
	/**
	 * fade out, fade in icons
	 * @param boolean inc
	 * @param resource obj
	 */
	trans: function(inc,obj) {
		var ref = this; 
		if(inc) {
			//alert('inc: true'); 
			obj['iconOn'].effect('opacity',{duration: ref.opt.duration, onComplete: function(el){
				obj['iconOn'].setStyle('display','none');
				obj['iconOff'].setStyle('visibility','hidden');
				obj['iconOff'].setStyle('display','block');
				obj['iconOff'].effect('opacity',{duration: ref.opt.duration}).start(0,1);
			}}).start(1,0);
		} else {
			//alert('inc: '+inc);
			obj['iconOff'].effect('opacity',{duration: ref.opt.duration, onComplete: function(el){
				obj['iconOff'].setStyle('display','none');
				obj['iconOn'].setStyle('visibility','hidden');
				obj['iconOn'].setStyle('display','block');
				obj['iconOn'].effect('opacity',{duration: ref.opt.duration}).start(0,1); 
			}}).start(1,0);
		}
	},
	/**
	 * inserts initial text within containing span el
	 * @param resource el
	 * @param boolean inc
	 */
	insertTxt: function(el,inc) {
		el.setHTML('<span>'+(inc?this.opt.on.text:this.opt.off.text)+'</span>'); 		
	},
	/**
	 * sets text of this.els[idx]
	 */
	updateTxt: function(idx,inc) {
		var str = !inc ? String(this.opt.on.text) : String(this.opt.off.text); 
		var el = (this.els[idx]).getElement('span'); 
		el.setText(String(str)); 
	},
	/**
	 * removes this.id from current collection
	 * @return boolean
	 */
	remove: function(id) {
		this.opt.previousID = id; 
		return (this.opt.collection).remove(id); 
	},
	/**
	 * determines this.id from id attr of this.els
	 * @TODO - make extensible... current relies on substr() method to strip off first 4 characters of attr's value
	 * @param resource el
	 * @return number
	 */
	identify: function(el) {
		var str = String(el.id); 
		var int = Number(str.substr(4,str.length)); 
		return int; 
	},
	/**
	 * saves current collection to Hash.Cookie object
	 */
	save: function() {
		var obj = new Object(); 
			obj[this.opt.hash_name] = this.opt.collection; 	
		(this.hash).extend(obj); 
		(this.hash).save();
	},
	/**
	 * builds current collection from Hash.Cookie obj if exists
	 * creates reference to this object on this.el element 
	 * adds mouseup event handler to this.el
	 * @see this.initialize();
	 */
	setup: function() {
		var ref = this; 
		(this.els).each(function(item,index){
			var idx = index; 
			var id = ref.identify(item);
			var inc = ref.collected(id); 
			
			ref.insertTxt(item,inc); 
			ref.insertImgs(item,inc); 

			item.addClass(inc ? ref.opt.on.className : ref.opt.off.className); 
			item.addEvent('mouseup',function(ev){
				ref.atn(id,idx); 
			}); 
			item.addEvent('click',function(ev){
				ref.stopEv(ev); 
			}); 
		}); 
	},
	/**
	 * collects or removes this.id from current collection, where appropriate
	 * @see this.setup(); 
	 */
	atn: function(id,idx) {
		var inc = this.collected(id); 
		if(!inc) {
			this.collect(id); 
		} else {
			this.remove(id); 
		}
		this.transmit(inc?0:1); 
		this.save(); 
		this.updateTxt(idx,inc); 
		this.classNames(idx,inc); 
		this.toggle(idx); 
		this.opt.onComplete();
	},
	/**
	 *
	 */
	transmit: function(atn) {
		var ajx = new Ajax(uri+'index.php?tpl=saved&s='+atn+'&aid='+this.opt.previousID,{method:'get'}).request();
	},
	/**
	 * Stop default event behavior
	 */
	stopEv: function(ev) {
		var event = new Event(ev);
			event.stop();
	}

}); 
ActivityCollector.implement(new Events);

