function TagControl() {

	this.script = '/php/tagcontrol.phtml';

	this.AttachObject = function(elName) {

		that = this;

		this.obj = document.getElementById(elName);
		if (this.obj) {
			this.obj.ajaxObject = this;
			this.obj.onclick = this.OnClick;
			this.obj.onselectstart = function() { return false; }

			var formObjects = this.obj.getElementsByTagName('FORM');
			for (var i=0; i < formObjects.length; ++i) {
				formObjects[i].ajaxObject = this;
				formObjects[i].onsubmit = function() { return this.ajaxObject.OnAddTags(this); };
			}

			var buttonObjects = this.obj.getElementsByTagName('BUTTON');
			for (var i=0; i < buttonObjects.length; ++i) {
				if (buttonObjects[i].className == 'senddata') {
					buttonObjects[i].ajaxObject = this;
					buttonObjects[i].onclick = function() { return this.ajaxObject.OnDataSend(this); };
				}
			}

			this.GetContainers();
			this.resultsContainer.onclick = this.OnClickResults;
			this.resultsContainer.ajaxObject = this;
		}
	}

	this.OnDataSend = function() {
		if (!this.objectId) return;

		req = new AJAX_Request();
		req.Add('_action', 'UpdateTags');
		req.Add('id', this.objectId);
		req.Add('tags', this.GetTags().join(','));
		req.Send(this.script, 'post', false);

		this.obj.style.display = 'none';

		var el = document.getElementById('cloud');
		if (el) {
			el.innerHTML = req.responseText;
		}
		return req.responseText;
	}

	this.OnNavigate = function(e) {
		e = e ? e : event;

    	keyCode = e.keyCode;

		// Вверх
    	if (keyCode == 38) {

    		if (that.resultItem < 1) return false;
    		--that.resultItem;

		// Вниз
    	} else if (keyCode == 40) {

    		if (that.resultItem >= (that.resultLength-1)) return false;
    		++that.resultItem;

    	} else {
    		return false;
    	}

    	items = that.resultsContainer.getElementsByTagName('P');
    	if (items) {
    		if (that.resultItem < items.length) {
    			that.SelectResultsItem(items[that.resultItem]);
    		}
    	}

    	return false;
    }

	this.SelectResultsItem = function (el) {
		if (this.resultOldItem) {
			this.resultOldItem.className = '';
		}

		this.resultOldItem = el;
		this.resultOldItem.className = 'active';
		if (this.resultOldItem.offsetTop > 75) {
			//divRes.scrollTop = resultOldItem.offsetTop - 75;
		} else {
			//divRes.scrollTop = 0;
		}
	}


	this.OnClickResults = function(e) {
		srcEl = e ? e.target : event.srcElement;

		if (srcEl.tagName == 'A') {
			//alert (srcEl.firstChild.nodeValue);
			//srcEl.parentNode.ajaxObject.inputObject.value = srcEl.firstChild.nodeValue;

			if(srcEl.id) {
				srcEl.parentNode.ajaxObject.AddTag(srcEl.firstChild.nodeValue.replace(/^([^-]+) - .+$/, '$1'), srcEl.id);
			} else {
				srcEl.parentNode.ajaxObject.AddTag(srcEl.firstChild.nodeValue);
			}

			srcEl.parentNode.ajaxObject.inputObject.value = '';
			srcEl.parentNode.style.display = 'none';
			srcEl.parentNode.ajaxObject.inputObject.focus();

		}
	}

	this.OnClick = function(e) {
		srcEl = e ? e.target : event.srcElement;

		if (srcEl.tagName == 'SUP') {
			// Удаляем таг
			parentEl = srcEl;

			// находим удаляемый таг
			while (parentEl && parentEl.tagName != 'DIV') {
				parentEl = parentEl.parentNode;
			}

			// удаляем таг
			if (parentEl) {
				parentEl.parentNode.removeChild(parentEl);
			}

			if (this.ajaxObject.tagsContainer.getElementsByTagName('DIV').length == 0) {
				this.ajaxObject.tagsContainer.innerHTML = 'не выбрано ни одного тэга';
			}

			return;
		}

		if (srcEl.className == 'item') {
			// Ух ты. Айтем! А какой? Если фаворит - то иди сюда, то есть, ТУДА!
			if (srcEl.parentNode.className == 'favourite') {
				this.ajaxObject.AddTag(srcEl.innerHTML.replace(/^\s+|\s+$/g, ''));
			}
		}

	}


	this.GetContainers = function() {
		var divs = this.obj.getElementsByTagName('DIV');

		for (var i=0; i < divs.length; ++i) {
			switch (divs[i].className) {
				case 'tags':
					this.tagsContainer = divs[i];
					break;
				case 'favourite':
					this.favouritesContainer = divs[i];
					break;
				case 'results':
					this.resultsContainer = divs[i];
					break;
			}
		}
	}


	// возвращает массив уже добавленных тагов или объектов, если objects = true
	this.GetTags = function(objects) {
		// Найдем контейнер
		var words = new Array();

		var wordEls = this.tagsContainer.getElementsByTagName('DIV');
		for (var i=0; i < wordEls.length; ++i) {

			if(objects) {
				if(wordEls[i].className == 'object') {
					words.push(wordEls[i].id);
				}
			} else {
				if(wordEls[i].className == 'item') {
					words.push(wordEls[i].innerHTML.replace(/<.+/, ''));
				}
			}

		}

		return words;
	}

	// возвращает массив уже добавленных объектов
	this.GetObjects = function() {

		return this.GetTags(true);

	}

	// проверяем добавлен таг уже или еще нет
	this.GotTag = function(tag) {
		var gotWord = false;
		var curTags = this.GetTags();
		tag = tag.toLowerCase();

		for (var j=0; j < curTags.length; ++j) {
			if (curTags[j].toLowerCase() == tag) {
				gotWord = true;
				break;
			}
		}

		return gotWord;
	}

	// добавляем в поле выбранных тагов (контейнер) таг или объект (если есть id)
	this.AddTag = function(tag, id, nosup) {

		var tag = tag.replace(/^\s+|\s+$/g, '');
		tag = tag.replace(/[^a-zA-Z0-9а-яА-Я ]/g, '');

		if (tag == '') return;

		if (this.GotTag(tag)) return;

		// убираем всякие лишние надписи из контейнера
		if (this.tagsContainer.getElementsByTagName('DIV').length == 0) {
			this.tagsContainer.innerHTML = '';
		}

		// добавляем в контейнер новый таг в формате <div class="item">таг<sup>x</sup></div>
		// или новый объект в формате <div class="object" id="_id">название объекта<sup>x</sup></div>
		var newDiv = document.createElement('div');
		if(id) {
			newDiv.className = 'object';
			newDiv.id = id;
			newDiv.innerHTML = tag;
			if(!nosup) {
				newDiv.innerHTML += '<sup>x</sup> ';
			}
		} else {
			newDiv.className = 'item';
			newDiv.innerHTML = tag + '<sup>x</sup> ';
		}
		this.tagsContainer.appendChild(newDiv);

	}

	this.AddFavouriteTag = function(tag) {
		var newDiv = document.createElement('span');
		newDiv.className = 'item';
		newDiv.innerHTML = tag;
		if(this.favouritesContainer)
			this.favouritesContainer.appendChild(newDiv);
	}


	this.OnAddTags = function(myForm) {
		// Добавляем тэги? Отлично!
		if (myForm.text.value == '') this.OnDataSend();
		var words = myForm.text.value.split(',');

		for (var i=0; i < words.length; ++i) {
			this.AddTag(words[i]);
		}
		myForm.text.value = '';
		this.resultsContainer.style.display = 'none';

		return false;
	}

	this.findPosX = function(obj) {
        var curleft = 0;
        if (obj.offsetParent) {
            while (obj.offsetParent) {
                curleft += obj.offsetLeft
                obj = obj.offsetParent;
            }
        } else if (obj.x) {
            curleft += obj.x;
        }
        return curleft;
    }

    this.findPosY = function(obj) {
        var curtop = 0;
        if (obj.offsetParent) {
            while (obj.offsetParent) {
                curtop += obj.offsetTop;
                obj = obj.offsetParent;
            }
        } else if (obj.y) {
            curtop += obj.y;
        }
        return curtop;
    }

	this.ShowObjectTags = function(objectId, el) {
		this.objectId = objectId;
		var i;


		if (el) {
			// Позиционирование

			var x = this.findPosX(el) + 0;
			var y = this.findPosY(el) + 0;
			this.obj.style.left = x + 'px';
			this.obj.style.top = y + 'px';
			this.obj.style.display = 'block';
		}

		this.tagsContainer.innerHTML = 'нет ни одной привязки к фильмам или персонам';

		if (objectId) {
			req = new AJAX_Request();
			req.Add('_action', 'GetObjectTags');
			req.Add('id', objectId);
			req.Send(this.script, 'get', false);

			var xml = req.responseXML.documentElement;
			cn = xml.getElementsByTagName('item');
			l = cn.length;

			for (i=0; i < l; ++i) {
				if (cn[i].childNodes[0]) {
					this.AddTag(cn[i].childNodes[0].nodeValue);
				}
			}
		}

		req = new AJAX_Request();
		req.Add('_action', 'GetFavouriteTags');
		req.Add('id', objectId);
		req.Send(this.script, 'get', false);
		if(this.favouritesContainer)
			this.favouritesContainer.innerHTML = 'Ваши любимые тэги:<br>';

		var xml = req.responseXML.documentElement;
		if(xml) {
			cn = xml.getElementsByTagName('item');
			l = cn.length;


			for (i=0; i < l; ++i) {
				if (cn[i].childNodes[0]) {
					this.AddFavouriteTag(cn[i].childNodes[0].nodeValue);
				}
			}
		}

		var inputs = this.obj.getElementsByTagName('INPUT');
		for (i=0; i < inputs.length; ++i) {
			if (inputs[i].type == 'text' && (inputs[i].name == 'text' || inputs[i].name == 'tagstext')) {
				if(inputs[i].name != 'tagstext')
					inputs[i].focus();
				inputs[i].obj = this.obj;
				inputs[i].ajaxObject = this;
				inputs[i].onkeydown = function(e) {
					if (!e) e = event;
					keyCode = e.keyCode;

					//
					if (keyCode == 27) {
						this.obj.style.display = 'none';
					} else

					// enter
					if (keyCode == 13) {
						if (this.ajaxObject.resultItem > -1) {
							items = this.ajaxObject.resultsContainer.getElementsByTagName('P');
							srcEl = items[this.ajaxObject.resultItem];
//							this.value = srcEl.firstChild.nodeValue;
							this.value = '';
							this.ajaxObject.resultItem = -1;
							this.ajaxObject.resultLength = 0;
						}

						if (e.ctrlKey) {
							this.ajaxObject.OnDataSend();
						}

						if(srcEl.id) {
							that.AddTag(srcEl.firstChild.nodeValue.replace(/^([^-]+) - .+$/, '$1'), srcEl.id);
						} else {
							that.AddTag(srcEl.firstChild.nodeValue);
						}

						return false;
					}

					this.ajaxObject.OnNavigate(e);
				}

				inputs[i].onkeyup = function(e) {
					if (this.value.length > 3) {

						this.ajaxObject.Lookup(this);
					} else {
						this.ajaxObject.resultsContainer.style.display = 'none';
					}
				}

				this.inputObject = inputs[i];
			}
		}
	}

	this.Lookup = function(obj) {
		el = obj;

		$(el).removeClass('pass').addClass('wait');

    	if (el.value == el.getAttribute('oldvalue')) return;

    	el.setAttribute('oldvalue', el.value);

    	if (el.value.length < 3) {
    		this.resultsContainer.style.display = 'none';
    		return;
    	}

    	resultReqStr = el.value.toLowerCase();

  		ac = new Date();

    	req = new AJAX_Request();
    	req.Add('q', resultReqStr);
    	req.Add('ac', ac.getTime());
    	req.Add('_action', 'LookupTags');

    	if(this.obj.id == 'divMessageTagControl')
    		req.Add('with_objects', 'true');

	   	req.ajaxObject = this;
    	req.Send(this.script, 'get', this.LookupResults);
	}


	// выводим результаты поиска
	this.LookupResults = function(req, status) {
//		alert(req.responseText);

		$('div.search input.inputtext').removeClass('wait').addClass('pass');

		cn = req.responseXML.documentElement;
		if (!cn)
			return;

		cn = cn.childNodes;

//		alert(cn.length);

		if (!cn)
			return;

		str = '';

		for (var i=0; i < cn.length; ++i) {
			if(cn[i].firstChild) {

				// ага таг нашли!
				if(cn[i].tagName == 'tag') {

//					str += '<p>' + cn[i].firstChild.nodeValue.replace(/</, '') + '</p>';

				// ага фильм или персону нашли!
				} else if(cn[i].tagName == 'film' || cn[i].tagName == 'person') {

					var id = '';
					var rus_name = '';
					var eng_name = '';
					var year = '';

					ce = cn[i].childNodes;
					for (var j=0; j < ce.length; ++j) {
						if(ce[j].firstChild) {
							if(ce[j].tagName == '_id')
								id = ce[j].firstChild.nodeValue;
							if(ce[j].tagName == 'rus_name')
								rus_name = ce[j].firstChild.nodeValue;
							if(ce[j].tagName == 'rus_lastname')
								rus_name += ' ' + ce[j].firstChild.nodeValue;
							if(ce[j].tagName == 'eng_name')
								eng_name = ce[j].firstChild.nodeValue;
							if(ce[j].tagName == 'eng_lastname')
								eng_name += ' ' + ce[j].firstChild.nodeValue;
							if(ce[j].tagName == 'year')
								year = ce[j].firstChild.nodeValue;
							if(ce[j].tagName == 'birth_year')
								year = ce[j].firstChild.nodeValue;
						}
					}

					str += '<a href="#" onclick="return false;" id="' + id + '">' + rus_name + ' - ' + eng_name + ' (' + year + ')' + '</a>';
				}
			}
		}

		var el = document.getElementById('divTagControl');
		if(!el)
			el = document.getElementById('divMessageTagControl');
		if (el) {
			el.ajaxObject.resultLength = cn.length;
			el.ajaxObject.resultItem = -1;
			if (cn.length == 0) {
				el.ajaxObject.resultsContainer.style.display = 'none';
			} else {
				el.ajaxObject.resultsContainer.style.display = 'block';
				el.ajaxObject.resultsContainer.innerHTML = str;
			}

		}
	}
}