Object.extend(Ajax.Request.prototype, {
  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.url = url;
    this.hasStarted = false;
    /*this.setOptions(options);
    if(!this.options.wait){
      this.start();
    }*/
  },
  start: function() {
  	if(!this.hasStarted) {
  	  this.hasStarted = true;
  	  this.request(this.url);
  	}
  },
  abort: function(){
  	this.transport.abort();
  }	
});

Object.extend(Ajax.Updater.prototype, {
   initialize: function(container, url, options) {
   	
    this.url = url;
	this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, param) {
      this.updateContent();
      onComplete(transport, param);
    }).bind(this);
	if(!this.options.wait)
      this.start();
  },
  start: function() {
  	if(!this.hasStarted) {
  	  this.hasStarted = true;
  	  this.request(this.url);
  	}
  },
  abort: function(){
  	this.transport.abort();
  }	
});

//Ajax.Updater.prototype.start = Ajax.Request.prototype.start;
//Ajax.Updater.prototype.abort = Ajax.Request.prototype.abort;

/**
 * Extended to make it easier to stopObserving when anonymous functions are used
 * as the observer.  Event.observe will now return an array containing all the 
 * stuff required to stop the observer.
 * Event.stopObserving has been extended to allow a single parameter to be passed in.
 * that parameter should be the array returned by Event.observe.
 */
Object.extend(Event, {_observe: Event.observe, _stopObserving: Event.stopObserving});
Object.extend(Event, {
	observe: function(element, name, observer, useCapture){
		Event._observe(element, name, observer, useCapture);
		return [element, name, observer, useCapture];
	},
	stopObserving: function(element, name, observer, useCapture){
	    if(arguments.length == 1){
	    	name = element[1];
	    	observer = element[2];
	    	useCapture = element[3];
	    	element = element[0];
	    }
		Event._stopObserving(element, name, observer, useCapture);
	}
});



/**
 * Define some globals for figuring out what type of element we have
 */

function Node() {}

Node.ELEMENT_NODE = 1;
Node.ATTRIBUTE_NODE = 2;
Node.TEXT_NODE = 3;
Node.CDATA_SECTION_NODE = 4;
Node.ENTITY_REFERENCE_NODE = 5;
Node.ENTITY_NODE = 6;
Node.PROCESSING_INSTRUCTION_NODE = 7;
Node.COMMENT_NODE = 8;
Node.DOCUMENT_NODE = 9;
Node.DOCUMENT_TYPE_NODE = 10;
Node.DOCUMENT_FRAGMENT_NODE = 11;
Node.NOTATION_NODE = 12;

/**
 * This section extends (or create in IE) the NodeList object
 * to allow for enumeration of read-only node lists (element.childNodes, etc)
 * A NodeList differs from an Array in a couple ways.
 * - It is specifically designed to hold Nodes (XML nodes or HTML elements)
 * - It is read only
 * - It is often "live" meaning that if the DOM changes, this list will often change
 *   without warning.
 * - It's much faster
 */
function IENodeList(node_list){
	var _real_node_list;
	this._real_node_list = node_list;
};

NodeList_Extensions = {
	elements:	function() {
					return this.inject([], function(elementNodes, element) {
					  if(element.nodeType == Node.ELEMENT_NODE)
						elementNodes.push(element);
					  return elementNodes;
					});
				},
	firstElement:	function(){
					return this.elements().first();
				},
	lastElement:	function(){
					return this.elements().last();
				},
	inspect:	Array.prototype.inspect				
};


Object.extend(IENodeList.prototype, Enumerable);
Object.extend(IENodeList.prototype, {
	_each:	function(iterator) {
		if(this._real_node_list){
			for (var i = 0; i < this._real_node_list.length; i++){
				iterator(this._real_node_list[i]);
			}
		}
	},
	first:		function(){ return this._real_node_list[0]; },
	last:		function(){ return this._real_node_list[this._real_node_list.length - 1]; },
	indexOf:	function(object) {
				for (var i = 0; i < this._real_node_list.length; i++)
					if (this._real_node_list[i] == object) return i;
				return -1;
			}
});
Object.extend(IENodeList.prototype, NodeList_Extensions);

if(typeof NodeList != 'undefined'){
	Object.extend(NodeList.prototype, Enumerable);	
	Object.extend(NodeList.prototype, {
		_each:		Array.prototype._each,
		first:		Array.prototype.first,
		last:		Array.prototype.last,
		indexOf:	Array.prototype.indexOf
	});
	Object.extend(NodeList.prototype, NodeList_Extensions);
}

/**
 * Build a browser independent NodeList object from a node list.
 * This does nothing in FireFox, but supplies a bunch of fixes in IE.
 */
function $NL(node_list){

	if(typeof IENodeList != 'undefined' || typeof node_list != 'NodeList'){
		return new IENodeList(node_list);
	}
	else{
		return node_list;
	}

}


//FEATURED IMAGE WIDGET
var featuredImageWidget = {
	featuredImages: [],
	singleFeaturedImage: function(inThumbnail, inPreview, inFullImg, inDescription) {
		this.thumbnail = inThumbnail;
		this.previewimg = inPreview;
		this.fullimg = inFullImg;
		this.description = inDescription;
	},
	addFeaturedImage: function(inObj) {
		this.featuredImages[this.featuredImages.length] = new this.singleFeaturedImage(inObj.thumbnail, inObj.previewimg, inObj.fullimg, inObj.description);
	},
	render: function() {
		//renders the featured images box
		this.featuredImages.each(function(featuredImage) {
			var alink = document.createElement('a');
			alink.setAttribute('href', 'javascript:;');
			var tnImg = document.createElement('img');
			tnImg.setAttribute('src',featuredImage.thumbnail);
			tnImg.setAttribute('alt',featuredImage.description);
			alink.appendChild(tnImg);
			featuredImage.alink = alink;
			$('featuredThumbs').appendChild(alink);
			Event.observe(alink, 'click', function(){featuredImageWidget.selectImage(featuredImage)});
		});
		this.selectImage(this.featuredImages.first());
		
		Event.observe(window, 'load', function() {
					//prepare overlay once the container has loaded
			var featuredImageWidgetOverlay = document.createElement('div');
			featuredImageWidgetOverlay.setAttribute('id', 'featuredImageWidgetOverlay');
			$('container').appendChild(featuredImageWidgetOverlay);
			Event.observe('featuredImageWidgetOverlay', 'click', function(){this.closeFullSize()}.bind(this));
			
			//prepare largeimagebox in overlay
			var featuredImageLarge = document.createElement('div');
			featuredImageLarge.setAttribute('id', 'featuredImageLarge');
			$('container').appendChild(featuredImageLarge);
			
			Event.observe('featuredImagePreviewImg', 'click', function(){this.showFullSize(this.featuredImages.selected)}.bind(this));
			
		}.bind(this));
		
	},
	selectImage: function(newFeaturedImage) {
		//called when a thumbnail is clicked
		this.featuredImages.each(function(featuredImage) {featuredImage.alink.removeClassName("tncurrent");});
		this.featuredImages.selected = newFeaturedImage;
		newFeaturedImage.alink.addClassName("tncurrent");
		setTimeout(function(){$('featuredImagePreviewImg').src = newFeaturedImage.previewimg;}.bind(this), 1); 
		$('featuredImagePreviewImg').show(); //fix render in ie6
		$('featuredImageDescription').innerHTML = newFeaturedImage.description;
	},
	showFullSize: function(featuredImage){
		//show overlay
		var containerWidth = "1000px";
		var containerHeight =  $('content').getHeight();
		var containerHeight = containerHeight + "px";
		$('featuredImageWidgetOverlay').style.width = containerWidth;
		$('featuredImageWidgetOverlay').style.height = containerHeight;
		$('featuredImageWidgetOverlay').style.display = 'block';
		
		//show largeimagebox
		$('featuredImageLarge').style.display = 'block';
		$('featuredImageLarge').innerHTML = "<div class=\"closeImg\"><a class=\"tnclose\" href=\"javascript:featuredImageWidget.closeFullSize();\">X</a></div><img src=\""+featuredImage.fullimg+"\" /><h3>"+featuredImage.description+"</h3>";

	},
	closeFullSize: function(){
		$('featuredImageLarge').style.display = 'none';
		$('featuredImageWidgetOverlay').style.display = 'none';
	}
}
