/**
	KAGallery - General gallery. Based on jQuery
	Rev: 7; Author: Magnus Persson, Palmarium;
*/

if(typeof(jQuery) === "undefined"){
	throw("KAGallery: jQuery is not present."); 
}

var KAGallery = new function(){
	/**
		Default render strategy for the gallery
	*/
	this.DefaultRender = function(gallery){
		gallery.html(""); 
	
		//render current image
		var ctrl = gallery.getCtrl(); 
		var main = $("<div class='"+KAGallery.Config.cssMain+"'>"); 
		var img = ctrl.getCurrent(); 
		
		$("<img width='100%' src='"+img.src+"'>").appendTo(main); 
		
		main.appendTo(gallery); 
	
		//render navigation
		var imgs = gallery.getImages(); 
		var curIndex = ctrl.getCurrentIndex();
	
		var nav = $("<div class='"+KAGallery.Config.cssNavigation+"'>");
		
		if(_navPrefix!=null) {
		    nav.append("<span class='"+KAGallery.Config.cssNavigationPrefix+"'>"+_navPrefix+"</span>"); 
		}
		
		for(var i=0, len=imgs.length; i<len; i++){
			if(i==curIndex){
				nav.append("<span class='"+KAGallery.Config.cssNavigationItemSelected+"'>"+(i+1)+"</span>"); 
			}else{
				var anchor = nav.append("<span class='"+KAGallery.Config.cssNavigationItem+"'><a href='javascript:KAGallery.getGallery("+gallery.index+").getCtrl().setImage("+i+")'>"+(i+1)+"</a></span>");
			}
		}
		
		gallery.append(nav);	 
	};
	 
	/** 
		Default controller for the gallery navigation.
	*/
	this.DefaultCtrl = function(gallery){
		var _index = 0; 
		
		this.setImage = function(index){
			_index = index;
			KAGallery.renderGallery(gallery, KAGallery.Config.renderStrategy)
		}; 
		this.getCurrent = function(){ 
			return gallery.getImages()[_index]; 
		};
		this.getImages = function(){
			return gallery.getImages(); 
		}; 
		this.getCurrentIndex = function(){
			return _index; 
		}; 
	}; 
	
	/**
		Main config. General configuration for all galleries
	*/
	this.Config = { 
		outputElementId: "gallery_output_", 
		renderStrategy: this.DefaultRender,
		controller: this.DefaultCtrl,
		cssMain: "KAMain", 		//default CSS class for the main photo element
		cssNavigation: "KANavigation", 		//default CSS class for the Navigation element
		cssNavigationItem: "KANavigationItem",
		cssNavigationItemSelected: "KANavigationItemSelected",
		cssNavigationPrefix: "KANavigationPrefix"
	}; 

	//private properties
	var _galleries = []; 
	var _galleryCount = 0;
	var _this = this; 
	var _navPrefix = null;
	
	
	/**
		outputElement may be an string-id or an DOM-object
	*/
	this.createGalleryInstance = function(outputElement, navPrefix){ //this.createGalleryInstance = function(outputElement){
		_galleryCount++;
        
        _navPrefix = navPrefix;
        
		//Wrap output element into a gallery object and assign methods directly
		var g = $(outputElement); 
		g.addImage = function(image){
			if(!this.images){
				this.images = []; 
			}
			
			if(typeof(image) === "string"){
				image = {src: image}; 
			}
			
			this.images[this.images.length] = image;
			return image;  
		}; 
		g.getImages = function(){
			return this.images; 
		}; 
		g.setCtrl = function(ctrl){
			this.ctrl = new ctrl(this); //instantiate controller  
		}; 
		g.getCtrl = function(){
			return this.ctrl; 
		}; 
		
		//assign the default controller
		g.setCtrl(this.Config.controller);
		//assign array index to gallery
		g.index = _galleries.length;  
		_galleries[_galleries.length] = g;
			
		return g; 
	};

	/**
		Init is called directly after the DOM is completely loaded. It preloads
		all gallery instances. When done, a render strategy renders them.
	*/
	this.init = function(){
		for(var i=0, len=_galleries.length; i<len; i++){			
			this.preloadGallery(_galleries[i], function(gallery){ _this.renderGallery(gallery, _this.Config.renderStrategy); }); 
		}
	}; 

	/**
		Preloads a gallery by loading each image it contains into the web browsers cache.
	*/
	this.preloadGallery = function(gallery, callback){
		var img, noi = 0; 
		var imageData = gallery.getImages(); 
	
		var load = function(){
			if(++noi === imageData.length){
				//all images loaded, trigger callback		
				callback(gallery);
			}
		}; 
				
		var error = function(){ throw("preload(): Error loading image!"); }; 
		var abort = function(){ throw("preload(): Loading image aborted!"); }; 

        if (imageData) {
		    for(var i=0, len = imageData.length; i<len; i++){
			    img = new Image(); 
    			
			    img.onload = load; 
			    img.onerror = error; 
			    img.onabort = abort; 
    			
			    img.src = imageData[i].src; 
			    imageData[i].cache = img; 
		    }
		}
	}; 

	/**
		Returns a gallery by its array id; 
	*/
	this.getGallery = function(galleryIndex){
		return _galleries[galleryIndex]; 
	}; 

	/**
		render is a strategy delegate for rendering a specific gallery
	*/
	this.renderGallery = function(gallery, render){
		render(gallery); 
	}
}

$(document).ready(function(){
	KAGallery.init(); 
}); 
