/**
 * Pod1 Core
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 *
 *
 * @category   Pod1
 * @package    Pod1_Core
 * @copyright  Copyright (c) 2009 Pod1 (http://www.pod1.com)
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

PodCore = Class.create();
PodCore.prototype = {

	initialize: function() {
		this.loadEvent 	= 'core:load';
    },
    
	evalTransport: function(transport) {
		try { response = eval('('+transport.responseText+')') } catch(e) { response = {} }
		return response;
	},
    
	evalWindowLoadScripts: function(content) {
		this.removeLoadObservers();
		var scripts = content.extractScripts();
		if(scripts) {
			for(var i=0; i<scripts.length; i++) {
				var script 	= scripts[i];
				var replace = script.gsub(/Event\.observe[\s\n\r]*\([\s\n\r]*window,[\s\n\r]*\'load\'/, "Event.observe(document, '%s'".replace('%s', this.loadEvent));
				content 	= content.replace(script, replace);
			}
			content.evalScripts();
		}
		return content;
	},
	
	removeLoadObservers: function() {
		Event.stopObserving(document, this.loadEvent);
		return this;
	},
	
	addToGarbage: function(instance, id, scope) {
		if(typeof podGarbage != 'undefined') {
			podGarbage.add(instance, id, scope);
		}
		return this;
	},
	
	removeFromGarbage: function(id, scope) {
		if(typeof podGarbage != 'undefined') {
			podGarbage.remove(id, scope);
		}
		return this;
	},
	
	cleanGarbage: function(scope) {
		if(typeof podGarbage != 'undefined') {
			podGarbage.clean(scope);
		}
		return this;
	},
	
	
	redirect: function(transport) {
		var response = this.evalTransport(transport);
		if(response.redirect) {
			window.location = response.redirect;
		}
	},
	
	destroy: function() {
		return this;
	}
}

/**************************** Garbage Disposal **************************/

PodGarbage = Class.create();
PodGarbage.prototype = {

	initialize: function() {
		this.instances = {
			global: {}
		};
    },
    
    add: function(instance, id, scope) {
    	var scope = this.getScope(scope);
    	if(!this.hasScope(scope)) {
    		this.instances[scope] = {};
    	}
    	this.instances[scope][id] = null;
    	this.instances[scope][id] = instance;
    	return this;
    },
    
    remove: function(id, scope) {
    	var scope = this.getScope(scope);
    	this.instances[scope][id] = null;
    	return this;
    },
    
    clean: function(scope) {
    	var scope 		= this.getScope(scope);
    	var instances 	= this.instances[scope];
    	for(var prop in instances) {
    		var instance = instances[prop];
    		if(typeof instance.destroy != 'undefined') {
    			instance.destroy();
    		}
    	}
    	return this;
    },

    getScope: function(scope) {
    	if(typeof scope == 'undefined') {
    		return 'global';
    	}
    	return scope;
    },
    
    hasScope: function(scope) {
    	return (
    		typeof scope != 'undefined' && 
    		typeof this.instances[scope] != 'undefined'
    	);
    }
}

/**************************** Sticky Element **************************/

StickyElement = Class.create();
StickyElement.prototype = {

	initialize: function(element) {
		if(!$$(element)[0]) { 
			return; 
		}
		this.element = $$(element)[0];
		this.base = this.element.cumulativeOffset();
		this.element.setStyle({'position': 'absolute', 'z-index': '99999', 'left': this.base.left+'px', 'top': this.base.top+'px'});
		Event.observe(window, 'scroll', this.update.bindAsEventListener(this));
    },
    
    update: function(event) {
		var offsets = document.viewport.getScrollOffsets();
		var top 	= this.element.getStyle('top').replace('px', '');
		if(this.effect) {
    		this.effect.cancel();
    	}
		if(this.base.top <= offsets.top) {
			this.effect = new Effect.Morph(this.element, {style: 'top: '+offsets.top+'px;', duration: 0.5});
		} else if(this.base.top > offsets.top && top != this.base.top) {
			this.effect = new Effect.Morph(this.element, {style: 'top: '+this.base.top+'px;', duration: 0.5});
		}
    }
}

/**************************** INITIALIZE ********************************/
var podGarbage = new PodGarbage();

