KSP = function () {
	var moduleData={},
		eventData={},
		debug=false,
		ec=0,
		createInstance = function ( moduleId ) {
			var instance = moduleData[moduleId].creator( new Sandbox() ),
				name, method;
			if( debug === true ) {
				for( name in instance ) {
					method = instance[name];
					if( typeof method == 'function' ) {
						instance[name] = function ( method, name ) {
							return function () {
								try {
									return method.apply( this, arguments );
								}
								catch( err ) {
									KSP.log( moduleId + ' - ' + name + '(): ' + err.message );
								}
							}
						}( method, name );
					}
				}
			}
			return instance;
		}
	return {
		register: function ( moduleId, creator ) {
			moduleData[moduleId] = {
				creator: creator,
				instance: null
			}
		},
		start: function ( moduleId ) {
			moduleData[moduleId].instance = createInstance( moduleId );
			moduleData[moduleId].instance.init();
		},
		stop: function ( moduleId ) {
			var data = moduleData[moduleId];
			if( data.instance ) {
				data.instance.destroy();
				data.instance = null;
			}
		},
		startAll: function () {
			var moduleId;
			for( moduleId in moduleData ) {
				if( moduleData.hasOwnProperty(moduleId) ) {
					this.start( moduleId );
				}
			}
		},
		stopAll: function () {
			var moduleId;
			for( moduleId in moduleData ) {
				if( moduleData.hasOwnProperty(moduleId) ) {
					this.stop( moduleId );
				}
			}
		},
		addListener: function ( events, handler, ctx, allowDupes ) {
			var l = events.length,
				i = 0;
			for( i; i < l; i++ ) {
				var j = 0,
					found=false,
					m;

				if( !eventData[events[i]] ) {
					eventData[events[i]] = [];
				}

				m = eventData[events[i]].length;

				for( j; j < m; j++ ) {
					if( handler == eventData[events[i]].handler && ctx == eventData[events[i]].ctx && !allowDupes ) {
						found = true;
					}
				}
				if( !found ) {
					eventData[events[i]].push({
						handler: handler,
						ctx: ctx
					});
				}
			}
		},
		dispatchEvent: function ( msgObj ) {
			var e = msgObj.e,
				data = [],
				i = 0,
				ev, l, prop;

			for( prop in msgObj.data ) {
				data.push( msgObj.data[prop] );
			}
			for( ev in eventData ) {
				if( ev == e ) {
					l = eventData[ev].length;
					for( i; i < l; i++ ) {
						var ce = eventData[ev][i];
						ce.handler.apply( ce.ctx, data );
					}
				}
			}
		},
		removeListener: function ( e, handler, ctx ) {
			var i = 0,
				l, ce;
			if( eventData[e] ) {
				l = eventData[e].length;
				for( i; i < l; i++ ) {
					ce = eventData[e][i];

					if( ce.handler == handler && ce.ctx == ctx ) {
						eventData[e].splice( i, 1 );
						break;
					}
				}
			}
		},
		clearEventType: function ( type ) {
			if( eventData[type] ) {
				eventData[type] = [];
			}
		},
		log: function ( msg ) {
			var ret, $c;
			ec++;
			ret = 'err' + ec + ': ' + msg;
			$c = $('#console');
			if( $c.length > 0 ) {
				var orig = $c.html();
				$c.html( orig + "\n" + ret );
			}
			else if( console ) {
				console.log( ret );
			}
			else {
				return ret;
			}
		}
	}
}();

Sandbox = function () {

	return {
		listen: function ( events, handler, ctx, allowDupes ) {
			if( typeof events == 'string' ) {
				events = [events];
			}
			KSP.addListener( events, handler, ctx, allowDupes );
		},
		notify: function ( msgObj ) {
			KSP.dispatchEvent( msgObj );
		},
		kill: function ( e, handler, ctx ) {
			KSP.removeListener( e, handler, ctx );
		},
		killType: function ( e ) {
			KSP.clearEventType( e );
		},
		refresh: function () {
			KSP.stopAll();
			KSP.startAll();
		}
	}
}

KSP.register('filter', function ( sandbox ) {
	var _,
		menuItems,
		portfolioItems;
	return {
		init: function () {
			_ = this;
			portfolioItems=$('.portfolio-article');
			menuItems = $('.side-menu-item').bind('click',_.hijackNav);
		},
		hijackNav: function ( e ) {
			var link=$(this);

			if( !!link.data('filter') ) {
				link.addClass('active').siblings().removeClass('active');
				_.routeFilter( link.data('filter') );
				e.preventDefault();
			}
			else if ( !!link.data('id') ) {
				_.routeTarget( link.data('id') );
				e.preventDefault();
			}
		},
		routeFilter: function ( f ) {
			var first, items, dy;
			items = portfolioItems.filter('[data-id="'+f+'"]').find('.project-blue').fadeOut();
			portfolioItems.not('[data-id="'+f+'"]').find('.project-blue').fadeIn();
			first = items.eq(0);
			if( !!first ) {
				dy = first.offset().top;
				$('html,body').animate({
					scrollTop: dy-114
				});
			}
		},
		routeTarget: function ( t ) {
			var obj = $('#'+t),
				dy = obj.offset().top;
			$('html,body').animate({
				scrollTop: dy-114
			});
		},
		destroy: function () {
			
		}
	}
} );

KSP.register('read-more', function ( sandbox ) {
	var _,
		expands;
	return {
		init: function () {
			_ = this;
			expands = $('.expand-btn').bind('click',_.toggleExpand).each(function(key,obj){
				var btn=$(this),
					txt=btn.parent('div'),
					article=txt.parent('article');

				btn.data( 'height', article.innerHeight() );

				if( article.innerHeight() >= txt.innerHeight() ) { //changed by pritika
					btn.hide();
				}
			});
		},
		toggleExpand: function ( e ) {
			var btn = $(this),
				txt = btn.parent('div'),
				article = txt.parent('article'),
				gradient = btn.siblings('.gradient'),
				targetHeight;

			!$.browser.msie ? _.toggleRotate(btn) : _.toggleFlip(btn);
			if( !($.browser.msie && $.browser.version < 9) ){
				gradient[btn.hasClass('contract') || !btn.hasClass('expand') ? 'fadeOut' : 'fadeIn' ]();
			}
			
			targetHeight = btn.hasClass('contract') || !btn.hasClass('expand') ? txt.innerHeight()+35 : btn.data('height');
			article.animate({
				height: targetHeight
			});

			e.preventDefault();
		},
		toggleRotate: function ( btn ) {
			var rotation = btn.hasClass('expand') ? '-180deg' : '0deg';
			btn.toggleClass('expand');
			btn.css({
				'-webkit-transform': 'rotate('+rotation+')',
				'-moz-transform': 'rotate('+rotation+')'
			});
		},
		toggleFlip: function ( btn ) {
			btn.toggleClass('contract');
		},
		destroy: function () {
			
		}
	}
} );
/*
KSP.register( 'home', function ( sandbox ) {
	var _,
		wrappers,
		nav,
		home,
		portfolio;
	return {
		init: function () {
			_ = this;
			// Store variables for nav, home, portfolio.
			nav = $('#menu');
			home = $('#home');
			portfolio = $('#project_book');
			wrappers = $('#home-wrapper,#home-image-wrapper').css('cursor','pointer').bind('click',_.hideWrapper);
		},
		hideWrapper: function ( e ) {
			wrappers.fadeOut();
			// Remove active class from home, and add to portfolio
			home.removeClass('active');
			portfolio.addClass('active');
			e.preventDefault();
		},
		destroy: function () {
			
		}
	}
} );
*/

$(function() {
	KSP.startAll();
});
