var comments_selector = undefined;
var users_selector = undefined;
var Page = new URI();
var lyncher = undefined;

var LynchCollection = new Class({

	initialize: function(){
		this.lynches = {};
		this.current = undefined;
	},
	
	'push': function(key, val){
		if (!$defined(this.current))
			this.current = val;
		
		this.lynches[key] = val;
	},
	
	get: function(key){
		return this.has(key) ? this.lynches[key] : false;
	},
	
	has: function(key){
		return (key in this.lynches);
	},
	
	show: function(id){
		var lynch = this.get(id);
		if (!lynch){
			return false;
		} else {
			if (lynch.loaded){
				this.current.hide();
				lynch.show();
			} else {
				new Request.JSON({
					url: lynch.url,
					method: 'post',
					secure: false,
					
					data: {
						action: 'lynch'
					},
					
					onRequest: function(){
						(function(){
							if (this.running){
								new Element('div', {id: 'lynch-cover', opacity: 0.6}).inject($('lynch'));
								
								users_selector.disable();
								comments_selector.disable();
							}
						}).delay(200, this);
					},
					
					onComplete: function(response) {
						var rating_holder = new Element('div', {
							'id': 'vote-' + id,
							'class': 'lyncher large rating'
						}).inject($('ratings'), 'top');
						
						var rating_num = new Element('span', {
							'class': (response.rating > 0) ? 'positive' : (response.rating < 0 ? 'negative' : 'neutral'),
							'html': ((response.rating > 0) ? '+' : (response.rating < 0 ? '&minus;' : '')) + Math.abs(response.rating)
						});

						if (response.voted || response.votable){
							rating_holder.adopt(new Element('span', {'class': 'darr', 'html': '&darr;'}))
										 .adopt(rating_num)
										 .adopt(new Element('span', {'class': 'uarr', 'html': '&uarr;'}));
						} else {
							rating_holder.addClass('noarrows');
							rating_holder.adopt(rating_num);
						}
						
						if (response.votable){
							lynch.bindRating();
						}
						
						if (response.voted){
							rating_holder.addClass('disabled').addClass(response.voted + 'voted');
						}
						
						lynch.user = response.user;
						lynch.loaded = true;
						
						var container = new Element('div', {
							id: 'lynch-' + lynch.id + '-display',
							'class': 'comments w' + response.lwidth,
							style: "background-image: url('/pictures/lynches/" + lynch.id + ".png')"
						});
						
						response.comments.each(function(comment){
							container.adopt(new Element('div', {
								style: 'top: ' + comment.y + 'px; left: ' + comment.x + 'px; width: ' + comment.width + 'px; height: ' + comment.height + 'px;'
							}).adopt(new Element('p', {'html': comment.text})));
						});
						
						$('lynch').adopt(container);
						
						users_selector.enable();
						comments_selector.enable();
						
						lynch.show();

						if ($('lynch-cover')) $('lynch-cover').destroy();
					},
					
					onFailure: function(response){
						alert('Ой, что-то пошло не так. Может, стоит перезагрузить страницу?');
						
						users_selector.enable();
						comments_selector.enable();
						
						if ($('lynch-cover')) $('lynch-cover').destroy();
					}
				}).send();
				
				this.current.hide();
			}
			
			this.current = this.lynches[id];
			
			//if ($('no-comments').hasClass('selected')){
			//	this.current.hide();
			//}
		}
	},
	
	hideAll: function(){
		for (var lynch in this.lynches)
			this.lynches[lynch].hide();
	}

});

var Lynch = new Class({
	
	initialize: function(obj){
		this.rating = undefined;
		this.own = false;
		
		if($type(obj) == 'element'){
			this.id = obj.id.slice(6);
			this.user = $$('.lyncher .user')[0].get('text');
			this.bindRating();
			this.loaded = true;
		} else {
			this.id  = obj.id;
			this.url = obj.url;
			this.loaded = false;
		}
	},

	bindRating: function(){
		var holder = $('vote-' + this.id);
		
		var callback = (function(rating, vote){
			var ratingHolder = $('lynch-' + this.id).getLast();
			ratingHolder.className = (rating > 0) ? 'positive' : (rating < 0 ? 'negative' : 'neutral');
			ratingHolder.set('html', ((rating > 0) ? '+' : (rating < 0 ? '&minus;' : '')) + Math.abs(rating));
		}).bind(this);
		
		this.rating = new Rating(holder, callback);
	},
	
	showLynch: function(){
		if (!this.loaded)
			return;
		
		$('lynch-' + this.id + '-display').setStyle('display', 'block');
	},
	
	show: function(){
		if (!this.loaded)
			return;
		
		$$('.lyncher .user')[0].set('html', this.user).set('href', '/user/' + this.user + '/');

		this.showLynch();
		
		$('vote-' + this.id).setStyle('display', 'block');

		Page.set('fragment', this.id).go();
	},
	
	hideLynch: function(){
		if (!this.loaded)
			return;
			
		$('lynch-' + this.id + '-display').setStyle('display', 'none');
	},
	
	hide: function(){
		if (!this.loaded)
			return;
		
		this.hideLynch();
		
		$('vote-' + this.id).setStyle('display', 'none');
	}

});

var collection = new LynchCollection();

window.addEvent('domready', function(){
	if ($('newlynch')){
		if (!Browser.Engine.trident){
			new Element('a', {
				'id': 'newlynch',
				'href': $('newlynch').get('alt'),
				'text': $('newlynch').get('text')
			}).replaces($('newlynch'));
		} else {
			$('newlynch').set('title', 'К сожалению, в Internet Explorer это не работает');
		}
	}

	if (!$('quick')){
		if ($$('div.lynchstarter')){
			new Rating($$('div.lynchstarter')[0]);
		}
	}
	
	// Отображение комментариев линча
	if ($('users')){
		var selects = {};
		var initial;
		
		$$('#users li').each(function(lynch){
			var id = lynch.id.slice(6);
			
			if (lynch.hasClass('selected')){
				collection.push(id, new Lynch(lynch));
				initial = id;
				lynch.removeClass('selected');
			} else {
				collection.push(id, new Lynch({id: id, url: lynch.getFirst().get('href')}));
			}
			
			selects[lynch.id] = function(){
				collection.hideAll();
				collection.show(id);
			}
		});
		
		var current = collection.has(Page.get('fragment')) ? Page.get('fragment') : initial;
		$('lynch-' + current).addClass('selected');
		
		users_selector = $('users').makeTabs({
			selects: selects
		});
		
		comments_selector = new TabsTransformer('comments-selector', {
			classes: {
				list: 'centered tabs'
			},
			
			'default': 'with-comments',
			
			selects: {
				'with-comments': function(){
					collection.current.showLynch();
				},
				
				'no-comments': function(){
					collection.current.hideLynch();
				}
			}
		});
		
		// Не очень хорошо, но пусть пока так
		((function(old_fragment){
			return function(){
				var new_fragment = document.location.hash.slice(1);
				if (new_fragment != old_fragment){
					if (!$('lynch-' + new_fragment).hasClass('selected')){
						collection.show(new_fragment);
						users_selector.select('lynch-' + new_fragment);
					}
					old_fragment = new_fragment;
				}
			}
		})(Page.get('fragment'))).periodical(100);
	} else if($('quick')) {
		comments_selector = new TabsTransformer('comments-selector', {
			classes: {
				list: 'centered tabs'
			},
			
			selects: {
				'with-comments': function(){
					$('quick').setStyle('display', 'block');
				},
				
				'no-comments': function(){
					$('quick').setStyle('display', 'none');
				}
			}
		});
	}
	
	// Форма ответа
	if ($('comment-form')){
		var reply = function(e){
			$('comment-form').setStyle('display', 'block');
			$('comment-form').inject($(e.target.className.slice(7)));
			$('comment-parent').value = e.target.className.slice(15);
			$('comment-area').focus();
		}
		
		$('comment-area').addEvents({
			keyup: function(e){
				$('comment-submit').set('disabled', (this.value.length == 0) ? 'disabled' : '');
			},
			
			keydown: function(e){
				$('comment-submit').set('disabled', (this.value.length == 0) ? 'disabled' : '');
			}
		});
		
		$('comment-form').addEvent('submit', function(e){
			e.stop();
			new Request.JSON({
				url: location.href,
				method: 'post',
				secure: false,
				
				data: {
					action: 'comment',
					comment: $('comment-area').value,
					parent:  $('comment-parent').value
				},
				
				onComplete: function(comment, text) {
					if (comment.status == 'ok'){
						if ($('nocomments')){
							$('nocomments').destroy();
						}
						
						if (!$('comment-parent').value){
							var tree = $('root-comments');
						} else {
							if (!$('comments_' + $('comment-parent').value)){
								$('comment_' + $('comment-parent').value).adopt(new Element('ul', { 'id': 'comments_' + $('comment-parent').value, 'class': 'comments' }));
							}
							
							var tree = $('comments_' + $('comment-parent').value);
						}
						
						$('comment-area').value = '';
						$('comment-form').setStyle('display', 'none');
						
						tree.adopt(
							new Element('li', {
								id: 'comment_' + comment.id
							}).adopt(
								new Element('dl').adopt(
									new Element('dt').set('text', 'Пользователь')
								).adopt(
									new Element('dd', {
										'class': 'user',
									}).adopt(
										new Element('a', {
											'class': 'user',
											href: '/user/' + comment.user + '/',
											text: comment.user
										}))
								).adopt(
									new Element('dt').set('text', 'Дата')
								).adopt(
									new Element('dd', {
										'class': 'date',
										text: comment.date
									})
								).adopt(
									new Element('dt').set('text', 'Сообщение')
								).adopt(
									new Element('dd', {
										'class': 'message',
										html: comment.message
									})
								).adopt(
									new Element('dt').set('text', 'Ответ')
								).adopt(
									new Element('dd', {
										'class': 'reply'
									}).adopt(
										new Element('span', {
											'class': 'dashed comment_' + comment.id,
											'text': 'ответить'
										}).addEvent('click', reply)
									)
								)));
					} else {
						alert('Что-то тут поломалось... Как вы это так сделали? В любом случае, комментарий, наверное, не отправился...');
					}
				}
			}).send();
		});
	
		$('add-comment').addEvent('click', function(){
			$('comment-form').setStyle('display', 'block');
			$('comment-form').inject($('comment-form-default-container'));
			$('comment-parent').value = '';
			$('comment-area').focus();
		});
		
		$$('.comments .reply span').each(function(comment){
			comment.addEvent('click', reply);
		});
	}
});

