var blGalleryBrowser = new Class({

	// TODO blImageBrowser
	Implements: [Options, blInterfaceEvents],

	events: {
	},

	options: {
		scrollElement:	null,
		smoothScroll:	true,
		mainLevel:		'project'
	},

	current:	{},
	cache:		{},
	scrollFx:	null,
	
	// initialization
	initialize: function(options, events) {

		this.setEvents(events);
		this.setOptions(options);

		if (this.options.scrollElement) {
			this.scrollElement = $(this.options.scrollElement);
			this.scrollElement.setStyle('overflow', 'hidden');

			//var BlFxScroll = new ;
			var BlFxScroll = Fx.Scroll.implement({
				smoothScroll : true,
				goToElement: function (element) {
					if (this.smoothScroll) {
						alert('smooth scroll');
						this.toElement(element);
					} else {
						alert('set position');
						var p = element.getPosition();
						this.set(p.x, p.y);
					}
				}
			});

			this.scrollFx = new BlFxScroll(this.scrollElement);
			this.scrollFx.smoothScroll = this.options.smoothScroll;
			
		}

		this.getEventManager().addEvent(this.getEvents().FOCUS_SET, this.setCurrentElementData.bind(this));
		this.getEventManager().addEvent(this.getEvents().ELEMENT_LOADED, this.setFocus.bind(this));

		this.pageRequest = new Request.HTML({
		//	link: 'cancel',
			currentUrl: null
		});
		this.pageRequest.addEvent('success', this.parsePageRequest.bind(this));

		this.initLevels();
		
	},

	browseLevel : function(link) {

		var level = this.getLevelFromLink(link);
		alert('browseLevel: ' + level);

		if (!this.getLevel(level))
			this.addLevel(level);

		var url = this.formatLinkUrl(link);
		this.setLevel(level, url);

		return false;

	},

	browsePage : function(link) {

		var model = this.current.model;
		if (model === null) {
			alert('ERROR: No model found');
			return false;
		}

		var func = "browse" + model;
		if (typeOf(this[func]) != 'function')
			this.loadPage(link);
		else
			this[func](link);

		return false;
	},

	initLevels : function () {
		alert('initLevels');
		
		//check main level
		var mainLevel = this.options.mainLevel;
		if (!this.getLevel(mainLevel)) {
			this.getLevel().addClass(mainLevel); // use first
		}

		// set level
		var level = this.getLevelFromLocation();
		if (this.getLevel(level))
			this.setLevel(level);
		else
			this.setLevel(mainLevel);

		// cache content
		var url = this.formatLinkUrl(window.location.href);
		this.cacheResult(url);

		this.getEventManager().fireEvent(this.getEvents().ELEMENT_LOADED, this.currentElement);
	},

	setLevel : function (l, url) {
		alert('> setLevel: ' + l + ' | url: ' + url);

		this.pageRequest.cancel();

		if (this.currentLevel == l) {
			alert('level is current level');
			return false;
		}

		if (!(el = this.getLevel(l))) {
			alert('no level element found');
			return false;
		}

		this.currentLevel = l;
		//this.currentElement = el;
		this.setCurrentElement(el);

		if (this.options.scrollElement)
			this.scrollFx.goToElement(this.currentElement);

		if (url)
			this.loadPage(url);
		
		return this.currentElement;
	},

	getLevel : function(l) {
		l = (l && l != '') ? '.' + l : '';
		return $('content').getElement(l+ '.level');
	},

	addLevel : function(l) {
		alert('> addLevel');

		var level = this.currentElement.clone(false);
		level.set('class', l + ' level');
		this.currentElement.adopt(level);
	},

	setCurrentElementData : function(el) {
		alert('> setCurrentElementData: ' + el);
		if (!el) el = this.currentElement;

		//alert(el);
		var metadata;
		if (!(metadata = el.retrieve('metadata'))) {
			var pager = el.getElement('.galleryPager');
			if (!pager) return;

			metadata = {
				page: pager.getElement('.currentPage').get('text').toInt(),
				pageCount: pager.getElement('.pageCount').get('text').toInt(),
				model: pager.get('title')
			};
			el.store('metadata', metadata);
		}

		this.current = metadata;
	},

	/**
	 * @param String|Element
	 */
	loadPage : function(link) {

		var pageUrl = this.formatLinkUrl(link)
		
		if (!pageUrl)
			return;

		alert('> load page: ' + pageUrl);
		
		// check cache
		if (!this.loadCachedResult(pageUrl)) {
			// do request
			//this.pageRequest.options.currentUrl = pageUrl;
			this.pageRequest.options.url = pageUrl;
			this.pageRequest.get();
		}
		
		this.trackPage(pageUrl);
	},

	parsePageRequest : function(responseTree, responseElements, responseHTML, responseJavaScript ) {
		alert('> parsePageRequest');
		
		if (!responseElements[0]) {
			alert('  - ERROR: no elements in response: ' + responseHTML);
			return;
		}
		el = responseElements[0];
		this.replaceCurrentElement(el);

		this.cacheResult(this.pageRequest.options.url, el);
		
		//var el = this.insertPageHtml(html);
		
	},


	insertPageHtml : function(pageHtml) {
		// TODO remove this, use set current element instead
		var outputEl = el || this.currentElement;
		outputEl.set('html', pageHtml);
		
		return outputEl;
	},

	setCurrentElement : function (el) {
		alert('> setCurrentElement: ');
		alert(el);

		if (this.currentElement == el)
			alert('  - element already set as current');

		if (this.currentElement)
			this.unsetCurrentElement();

		this.currentElement = el;
		this.getEventManager().fireEvent(this.getEvents().ELEMENT_LOADED, this.currentElement);
	},

	unsetCurrentElement : function () {
		this.releaseFocus();
		this.currentElement = null;
	},

	replaceCurrentElement : function (el) {
		if (!this.currentElement) {
			alert("ERROR: no current element set");
			return;
		}

		el.replaces(this.currentElement);
		this.setCurrentElement(el);
	},

	cacheResult : function(url, el) {
		alert('> cacheResult');

		var cacheEl = el || this.currentElement;

		var cacheClone = cacheEl.clone(true, true);
		this.cache[url] = cacheClone;
	},

	loadCachedResult : function(url) {
		var cachedEl = this.cache[url];
		if (!cachedEl)
			return false;

		alert("load from cache: " + url);
		alert(this.cache);

		this.replaceCurrentElement(cachedEl);

		return true;
	},


	setFocus : function(el) {
		alert('> setFocus:', el);

		if (!el && this.currentElement)
			el = this.currentElement;
		if (typeOf(el) != "element")
			return;

		this.releaseFocus();

		el.addClass('focus');
		this.getEventManager().fireEvent(this.getEvents().FOCUS_SET, el);
		
	},

	releaseFocus : function(el) {
		if (!el && this.currentElement)
			el = this.currentElement;
		if (typeOf(el) != "element")
			return;

		if (!el.hasClass('focus'))
			return;

		alert('> releaseFocus');
		
		el.removeClass('focus');
		this.getEventManager().fireEvent(this.getEvents().FOCUS_RELEASED, el);
	},

	formatLinkUrl : function(link) {

		var url = false;

		if (typeOf(link) == 'string')
			url = link;
		else if (typeOf(link) == 'element')
			url = link.get('href');

		if (!url) return false;

		// remove server
		if(url.indexOf('://') != -1) {
			url = url.substr(url.indexOf('://') + 3); // remove protocol
			url = url.substr(url.indexOf('/')); // remove server
		}

		// anchor link to absolute url
		if (url.substr(0, 1) == '#') {
			var base = window.location.href;
			if (base.indexOf('/level/') != -1)
				base = base.substr(0, base.indexOf('/level/'));
			if (base.indexOf('#') != -1)
				base = base.substr(0, base.indexOf('#'));

			url = base + url;
		}

		if (url.indexOf('/level/') != -1)
			return url;

		else if (url.indexOf('#') != -1)
			return url.replace('#', '/level/'); // set level param

		else
			return url += '/level/' + this.options.mainLevel;

		return url;
		
	},

	getLevelFromLink : function(link) {
		return this.getLevelFromUrl(link.get('href'));
	},
	
	getLevelFromLocation : function() {
		return this.getLevelFromUrl(window.location.href);
	},
	
	getLevelFromUrl : function(url) {
		
		var level;
		try {
			if (url.indexOf('#') == -1)
				throw "no level found";

			level = url.substr(url.indexOf("#") + 1);
			if (level == '')
				throw "no level found";
		} catch (e) {
			level = this.options.mainLevel;
		}

		return level;
		
	},

	trackPage : function(url) {
		// ga tracking
		if (typeof(pageTracker) != 'undefined')
			pageTracker._trackPageview(url);
	}

});
