document.documentElement.id = "js";

/* Fix for attrNames with gyphen */
Selectors.RegExps.combined = (/\.([\w-]+)|\[([\w-]+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g);

var pBlock = new Class({

	initialize: function(el,initTag){
		this.el = el;

		this.fx = new Fx.Tween(this.el,{
			'duration': 300,
			'fps': 30,
			'link': 'cancel'
		});

		/* Some magic for Opera 10.50, however can't determine exactly 10.10 lol */
		if (Browser.Engine.presto && Browser.Engine.version == '960') {
			this.fx.addEvent('complete',function() {
				if (this.el.getStyle('text-indent') == '0px') {
					this.el.setStyle('text-indent','0.01px');
				}
			}.bind(this));
		}
		/* end magic */

		this.fx_width = this.el.getSize().x;

		// Init Items & state
		this.items = [];
		this.initState = [];
		this.el.getElements('.portfolio-item-list-item').each(function(item,index) {
			var blockItem = new Hash({
			    el: item,
				index: index
			});
			this.items.push(blockItem);
			this.initState[index] = index;
		}.bind(this));

		this.filtersCashe = this.casheFilters();

		this.state = $A(this.initState);

		this.current = this.items[0];
		
		// Create Nav
		this.nav = new Element('span',{ 'class':'portfolio-item-nav'})
		this.nav.addEvents({
			'disable': function() {
				this.addClass('js-invisible');
			},
			'enable': function() {
				this.removeClass('js-invisible');
			}
		});
		this.wrap = this.el.getParent();
		this.wrap.addEvents({
			'disable': function() {
				this.addClass('js-hidden');
			},
			'enable': function() {
				this.removeClass('js-hidden');
			}
		});
		this.prev = new Element('span',{ 'class':'portfolio-item-nav-item portfolio-item-nav-prev', 'title':'Назад'}).inject(this.nav);
		this.nav.appendText(' ');
		this.items.each(function(item,index){
			item.dot = new Element('span',{ 'class':'portfolio-item-nav-item', 'title':item.el.get('text').clean() }).inject(this.nav);
			item.dot.addEvents({
				'click': function() {
					if (this.current.index != item.index) {
						this.goTo(item.index);
					}
				}.bind(this),
				'disable': function() {
					this.removeClass('portfolio-item-nav-item-active');
				},
				'enable': function() {
					this.addClass('portfolio-item-nav-item-active');
				}
			});
			item.el.addEvents({
				'disable': function() {
					item.el.addClass('js-hidden');
					item.dot.addClass('js-hidden');
				},
				'enable': function() {
					item.el.removeClass('js-hidden');
					item.dot.removeClass('js-hidden');
				}
			});
			this.nav.appendText(' ');
		}.bind(this));
		this.next = new Element('span',{ 'class':'portfolio-item-nav-item portfolio-item-nav-next', 'title':'Вперёд' }).inject(this.nav);
		this.nav.inject(this.el,'after');

		// Next&Prev events
		this.prev.addEvents({
			'click': function() {
				if (!this.isFirst(this.current.index)) {
					this.goTo(this.state[this.state.indexOf(this.current.index) - 1]);
				}
			}.bind(this),
			'disable': function() {
				this.addClass('portfolio-item-nav-item-inactive');
			},
			'enable': function() {
				this.removeClass('portfolio-item-nav-item-inactive');
			}
		});
		this.next.addEvents({
			'click': function() {
				if (!this.isLast(this.current.index)) {
					this.goTo(this.state[this.state.indexOf(this.current.index) + 1]);
				}
			}.bind(this),
			'disable': function() {
				this.addClass('portfolio-item-nav-item-inactive');
			},
			'enable': function() {
				this.removeClass('portfolio-item-nav-item-inactive');
			}
		});

		this.goTo(0);

	},

	casheFilters: function(){
		var result = new Hash();
		if ($chk(this.el.getProperty('data-tags'))) {
			this.el.getProperty('data-tags').split(' ').each(function(tag){
				result[tag] = $A(this.initState);
			}.bind(this));
		}
		this.items.each(function(item, index) {
			if ($chk(item.el.getProperty('data-tags'))) {
				item.el.getProperty('data-tags').split(' ').each(function(tag){
					result[tag] = result[tag] || [];
					result[tag].include(index);
				}.bind(this));
			}
		});
		return result;
	},

	isFirst: function(index, where) {
		if (where){
			return where.indexOf(index) == 0;
		} else {
			return this.state.indexOf(index) == 0;
		}
	},

	isLast: function(index, where) {
		if (where){
			return where.indexOf(index) + 1 == where.length;
		} else {
			return this.state.indexOf(index) + 1 == this.state.length;
		}
	},

	goTo: function(where){
		if ($chk(where)) {
			var from = this.current.index;
			this.fx.start('text-indent', - this.state.indexOf(where) * this.fx_width);
			this.items[from].dot.fireEvent('disable');
			this.items[where].dot.fireEvent('enable');
			if (this.isFirst(from)) {
				this.prev.fireEvent('enable');
			}
			if (this.isLast(from)) {
				this.next.fireEvent('enable');
			}
			if (this.isFirst(where)) {
				this.prev.fireEvent('disable');
			}
			if (this.isLast(where)) {
				this.next.fireEvent('disable');
			}

			this.current = this.items[where];

		}
	},

	filter: function(input){
		if (!(input.length == 0 && this.state.length == 0)) {
			// if we have no current
			if (!$chk(this.current) || input.indexOf(this.current.index) == -1) {
				this.current = this.items[input[0]];
			}

			// turn elements on and off again
			this.initState.each(function(index) {
				if (this.state.indexOf(index) != -1) {
					if (input.indexOf(index) == -1) {
						this.items[index].dot.fireEvent('disable');
						this.items[index].el.fireEvent('disable');
					}
				} else {
					if (input.indexOf(index) != -1) {
						this.items[index].el.fireEvent('enable');
					}
				}
			}.bind(this));

			if (input.length) {
				this.fx.set('text-indent', - input.indexOf(this.current.index) * this.fx_width);

				// check next & prev
				if (!this.isLast(this.current.index, input)) {
					this.next.fireEvent('enable');
				} else if (!this.isLast(this.current.index) && this.isLast(this.current.index, input)) {
					this.next.fireEvent('disable');
				}
				if (this.isFirst(this.current.index) && !this.isFirst(this.current.index, input)) {
					this.prev.fireEvent('enable');
				} else if (!this.isFirst(this.current.index) && this.isFirst(this.current.index, input)) {
					this.prev.fireEvent('disable');
				}
				
				// disable the nav if need
				if (input.length == 1) {
					this.nav.fireEvent('disable');
				}
				
				// enable the whole block if need
				if (this.state.length == 0) {
					this.wrap.fireEvent('enable');
				}

				// enable the nav if need
				if (this.state.length < 2 && input.length > 1) {
					this.nav.fireEvent('enable');
				}

				this.items[this.current.index].dot.fireEvent('enable');

			} else {
				// disable the whole block, nullify current (maybe bug), hide the nav
				this.current = null;
				this.wrap.fireEvent('disable');
				if (this.state.length != 1) {
					this.nav.fireEvent('disable');
				}
			}
			this.state = $A(input);

			/* opera -_- */
			if (Browser.Engine.presto) {
				this.nav.setProperty('style','text-align:center');
				this.nav.removeProperty('style');
			}
		}
	}
});

var TagFilter = new Class({
	initialize: function(){
		this.blocks = [];
		this.currentTag = 'all';
		this.currentMode = '';
		this.navItems = new Hash();
		this.allTags = [];
		this.allModes = [];
		
		
		// Init History
		this.history = HistoryManager.register(
			'js/',
			[''],
			function(values) {
				this.currentTag = values[0].split('/')[0];
				this.currentMode = values[0].split('/')[1];
				this.filter(values[0]);
				this.history.setValue('');
			}.bind(this),
			function(values) {
				return 'js/'+values[0];
			}.bind(this),
			'js/(.+)'
		);

		// Init blocks
		$$('.portfolio-item-list').each(function(block) {
			this.blocks.push(new pBlock(block));
		}.bind(this));

		// Add events to links
		$$('.portfolio-nav-item-tag').each(function(el){
			var tag = el.get('href').replace(/#(js\/)?/,'');
			if (tag == '') {
				tag = 'all';
			}
			this.navItems[tag] = el.getParent();
			el.addEvent('click', function() {
				var filterString = tag + ($chk(this.currentMode) ? (($chk(tag)?'/':'') + this.currentMode) : '');
				if (this.currentTag != tag) {
					// here we must change the links to new ones
					HistoryManager.setState('js/'+ filterString);
					this.filter(filterString);
					this.currentTag = tag;
				}
				return false;
			}.bind(this));
		}.bind(this));
		
		$$('.portfolio-nav-item-mode').each(function(el){
			var mode = el.get('href').replace(/#(js\/all\/)?/,'');
			this.navItems[mode] = el.getParent();
			el.addEvent('click', function() {
				var filterString = ($chk(this.currentTag) ? (this.currentTag + '/') : '') + mode;
				if (this.currentMode != mode) {
					HistoryManager.setState('js/' + filterString);
					this.filter(this.currentTag + '/' + mode);
					this.currentMode = mode;
				} else {
					HistoryManager.setState('js/' + this.currentTag);
					this.filter(this.currentTag||'');
					this.currentMode = '';
				}
				return false;
			}.bind(this));
		}.bind(this));

	},

	filter: function(input){
		var tags = input.split(/\//);
		this.navItems.each(function(item) {
			item.removeClass('portfolio-nav-item-selected');
		});
		tags.each(function(tag) {
			if (tag == '') {
				tag = 'all';
			}
			this.navItems[tag].addClass('portfolio-nav-item-selected');
		}.bind(this));
		
		this.blocks.each(function(block){
			var resultFilter = [];
			tags.each(function(tag,index) {
				var array = [];
				if (tag == 'all' || tag == '') {
					array = $A(block.initState);
				} else {
					array = block.filtersCashe[tag]||[];
				}

				if (index == 0) {
					resultFilter = array;
				} else {
					resultFilter = resultFilter.filter(function(item) {
						return array.contains(item);
					})
				}
			});
			block.filter(resultFilter);
		});
	}
});

window.addEvent('domready', function() {
	HistoryManager.initialize();

	var filter = new TagFilter();

	$$('.portfolio-item A[href]').each(function(el) {
		el.set('target', '_blank');
		// replace it with onclick js opener with choices
	});

	HistoryManager.start();
});
