function TagChooser () {}

TagChooser.all_tags = -1;
TagChooser.memorized_tags = -1;
TagChooser.tag_field = -1;
TagChooser.recent_tags_cookie_name = "recently_used_tags";
TagChooser.recent_tags_save_amount = 20;
TagChooser.max_tags_allowed = 15;
TagChooser.max_tags_allowed_before_warning = 3;

TagChooser.setTagField = function TagChooser_setTagField (element_name) {
	TagChooser.tag_field = Core.getElementU(element_name);
	if (TagChooser.tag_field == null) {
		TagChooser.tag_field = -1;
	}
}

TagChooser.isTagFieldSet = function TagChooser_isTagFieldSet() {
	return (TagChooser.tag_field != -1) ? 1 : 0;
}

TagChooser.tagIt = function TagChooser_tagIt(tag_clicked) {
	if(TagChooser.isTagFieldSet()) {
		if (TagChooser.isTagAlreadyChoosen(tag_clicked, TagChooser.tag_field.value)) {
			TagChooser.removeTagFromChoosenList(tag_clicked);
			TagChooser.highlight(tag_clicked);
		} else {
         if (TagChooser.blockTagAdding()) {
            return;
         }
		   TagChooser.addTagToChoosenList(tag_clicked);
			TagChooser.highlight(tag_clicked);
		}
	}
}

TagChooser.removeTagRestrictedSymbols = function TagChooser_removeTagRestrictedSymbols(t) {
	if(t != null && t != "") {
		t = t.replace(/[\?|~|`|\^|\(|\)|\[|\]|\{|\}|<|>|\||\=|;|,|:]/g, "");
		return t;
	}
	return "";
}


TagChooser.removeTagFromChoosenList = function TagChooser_removeTagFromChoosenList(t) {
	if (TagChooser.tag_field != -1) {
		choosen_tags = TagChooser.tag_field.value;

		t = t.replace(/\//g, "\\/");
		t = t.replace(/\+/g, "\\+");

		var retest1 = eval("/^" + t + " /ig");
		var retest2 = eval("/ " + t + " /ig");
		var retest3 = eval("/ " + t + "$/ig");
		var retest4 = eval("/^" + t + "$/ig");

		TagChooser.tag_field.value = TagChooser.tag_field.value.replace(retest1, '');
		TagChooser.tag_field.value = TagChooser.tag_field.value.replace(retest2, ' ');
		TagChooser.tag_field.value = TagChooser.tag_field.value.replace(retest3, '');
		TagChooser.tag_field.value = TagChooser.tag_field.value.replace(retest4, '');
	}
}

TagChooser.addTagToChoosenList = function TagChooser_addTagToChoosenList (t) {
	if (TagChooser.tag_field != -1) {
		TagChooser.tag_field.value += ' ' + t;
	} 
}

TagChooser.cleanUpTagField = function TagChooser_cleanUpTagField () {
	if (TagChooser.isTagFieldSet()) {
		TagChooser.tag_field.value = TagChooser.cleanUpTagText(TagChooser.tag_field.value);
	}
}

function t_join(q_str) {
   q_str = q_str.replace(/\x20+/g, " ");
   q_str = q_str.replace(/^.\x20/,"");
   q_str = q_str.replace(/\x20.$/,"");
   q_str = q_str.replace (/\x20/g, "_");
   q_str = q_str.replace(/"/g, "");
   return q_str;
}

function joinTag(text) {
	if(text != null && text != ""){
		if(text.match("\"")) {
         var quoted_text = '';
         quoted_text = text.match(/"[^"]*"/);
         if (quoted_text != null) {
            var replacement = t_join(quoted_text[0]);
	   		var tag_j = text.replace(/"[^"]*"/g , replacement);
   			return tag_j;
         } else {
            return text;
         }
		} else {
			return text;
		}
	} else {
		return "";
	}
}

TagChooser.cleanUpTagText = function TagChooser_cleanUpTagText(text) {
	if(text != null && text != -1) {
		text = text.toLowerCase();
		text = text.replace(/\n/g, " ");
		text = text.replace(/  */g, " ");
		text = TagChooser.removeTagRestrictedSymbols(text);
		text = joinTag(text)
		return text;
	}
	return null;
}


TagChooser.isTagAlreadyChoosen = function TagChooser_isTagAlreadyChoosen (choosen_tag, compare_text) {

	if(compare_text != null && compare_text != -1) {
		choosen_tag = choosen_tag.replace(/\//g, "\\/");
		choosen_tag = choosen_tag.replace(/\+/g, "\\+");

		var retest1 = eval("/^" + choosen_tag + " /ig");
		var retest2 = eval("/ " + choosen_tag + " /ig");
		var retest3 = eval("/ " + choosen_tag + "$/ig");
		var retest4 = eval("/^" + choosen_tag + "$/ig");

		return (retest1.test(compare_text) || retest2.test(compare_text) || retest3.test(compare_text) || retest4.test(compare_text));
	}

	return null;
}

TagChooser.getTagDiff = function TagChooser_getTagDiff(to_compare, compare_with) {
	var output_text = "";

	if (to_compare == null || to_compare == "") {
		return null;
	}

	var to_compare_array = to_compare.split(" ");
        //removing doubles in array
	to_compare_array = Core.getArrayUnique(to_compare_array);

	for (var x in to_compare_array) {
		if(to_compare_array[x] != '' && to_compare_array[x] != null && to_compare_array[x] != ' ' && to_compare_array[x] != '\n') {
			if(!TagChooser.isTagAlreadyChoosen(to_compare_array[x], compare_with)) {
				output_text += ' ' + to_compare_array[x];
			}
		}
	}

	if (output_text.length < 1) return null;

	return output_text;
}

TagChooser.reIndexTags = function TagChooser_reIndexTags () {
	TagChooser.cleanUpTagField();

	var start = new Date().getTime();

	var spans = document.getElementsByTagName("span");

	TagChooser.all_tags = new Array();

	for (var i=0; i<spans.length; i++) {
		var s = spans.item(i);

		if (s.id.indexOf('tag-') > -1) {
			var tag = s.id.substr(4);

			if (!TagChooser.all_tags[tag]) {
				TagChooser.all_tags[tag] = new Array(s);
			} else {
				try {
					var otherSpansForThisTag = TagChooser.all_tags[tag];
					otherSpansForThisTag.push(s);
					TagChooser.all_tags[tag] = otherSpansForThisTag;
				} catch (e) {
					Logger.log(e);
				}
			}
		}
	}

	var duration = new Date().getTime() - start;

	//log('done with reindexing in ' + duration);
}

TagChooser.memorizeCurrentTags = function TagChooser_memorizeCurrentTags () {
	if (TagChooser.tag_field != -1 && TagChooser.memorized_tags == -1) {
		TagChooser.memorized_tags = TagChooser.tag_field.value;
	}
}

TagChooser.flushMemorizedTags = function TagChooser_flushMemorizedTags () {
	TagChooser.memorized_tags = -1;
}

TagChooser.getMemorizedTags = function TagChooser_getMemorizedTags () {
	return TagChooser.memorized_tags;
}

TagChooser.isMemorizedSet = function TagChooser_isMemorizedSet () {
	return (TagChooser.memorized_tags != -1 && TagChooser.memorized_tags != null) ? 1 : 0;
}



TagChooser.getArrayOfTagsFromString = function TagChooser_getArrayOfTagsFromString (tags_string) {
        tags_string = tags_string.replace('  ', ' ');

        tags_string = tags_string.split(" ");

	var tags_string_out = new Array();

	for (i=0; i<tags_string.length; i++) { 
		
		tags_string_out[tags_string[i]] = 1;
	}

        return tags_string_out;
}

TagChooser.getCursorPosititon = function TagChooser_getCursorPosition() {
	if (TagChooser.isTagFieldSet()) {
		if (document.selection) {
			TagChooser.tag_field.focus();
			var range = document.selection.createRange();
			var stored_range = range.duplicate();
			stored_range.moveToElementText(TagChooser.tag_field);
			stored_range.setEndPoint('EndToEnd', range );
			TagChooser.tag_field.selectionStart = stored_range.text.length - range.text.length;
			TagChooser.tag_field.selectionEnd = TagChooser.tag_field.selectionStart + range.text.length;
			return TagChooser.tag_field.selectionStart;
		} else if (TagChooser.tag_field.selectionStart || TagChooser.tag_field.selectionStart == '0') {
			TagChooser.tag_field.focus();
			return TagChooser.tag_field.selectionStart;
		}
	}
}

TagChooser.setCursorPosition = function TagChooser_setCursorPosition (pos) {
	if (TagChooser.isTagFieldSet()) {
		if (document.selection) {
			TagChooser.tag_field.focus();
			var range = TagChooser.tag_field.createTextRange();
			range.collapse(true);
			range.moveStart("character", pos);
			range.moveEnd("character", 0);
			range.select();
		} else if (TagChooser.tag_field.selectionStart || TagChooser.tag_field.selectionStart == '0') {
			TagChooser.tag_field.selectionStart = pos;
		}
	}
}

TagChooser.prev_tags_highlighted = null;

TagChooser.highlight = function TagChooser_highlight (tag_to_highlight) {
	if (!TagChooser.isTagFieldSet()) {
		return;
	}

	if (TagChooser.all_tags == -1) {
		TagChooser.reIndexTags();
	}
	
	if (TagChooser.memorized_tags == -1) {
		TagChooser.memorizeCurrentTags();
	}

        var pos = TagChooser.getCursorPosititon();
	TagChooser.cleanUpTagField();
	TagChooser.setCursorPosition(pos);

	var array_to_process = TagChooser.all_tags;

	if (tag_to_highlight == null) {
		if (TagChooser.prev_tags_highlighted == null) {
			TagChooser.prev_tags_highlighted = '';
		}

		array_to_process = TagChooser.getArrayOfTagsFromString(TagChooser.prev_tags_highlighted  +   ' ' + TagChooser.tag_field.value);
	}

	TagChooser.prev_tags_highlighted = TagChooser.tag_field.value;

	for (tag in TagChooser.all_tags) {

		if (tag_to_highlight != null) {
			tag = tag_to_highlight;
		} else if (!array_to_process[tag]) {
			continue;
		}

		var allSpansForThisTag = TagChooser.all_tags[tag];
		if (TagChooser.isTagAlreadyChoosen(tag, TagChooser.tag_field.value)) {
			for (var i in allSpansForThisTag) {
				var tag_span = allSpansForThisTag[i];
				if (tag_span != null) {
					if (tag_span.className.indexOf(' sel') == -1) {
						tag_span.className += ' sel';
					}
				}
			}
		} else {
			for (var i in allSpansForThisTag) {
				var tag_span = allSpansForThisTag[i];

				if (tag_span != null) {
					if (tag_span.className.indexOf(' sel') != -1) {
						tag_span.className = tag_span.className.substr(0, tag_span.className.indexOf(' sel'));
					}
				}
			}
		}

		if (tag_to_highlight != null) {
			return;
		}
	}
}

TagChooser.updateRecentTags = function TagChooser_updateRecentTags (data) {
	var output = "";
	var check_with_cookie = "";
	var recently_used_tags = getCookie(TagChooser.recent_tags_cookie_name);
	// Logger.log("before: " + recently_used_tags);

	// checking if there were tags previously added to the photo
	if (TagChooser.isTagFieldSet()) {
		if (TagChooser.isMemorizedSet()) {
			// Logger.log("memorized: " + TagChooser.getMemorizedTags());
			check_with_cookie = TagChooser.getTagDiff(data, TagChooser.getMemorizedTags());
			// Logger.log("diff from memorized: " + check_with_cookie);
		} else {
			check_with_cookie = data;
			// Logger.log("empty memory: " + check_with_cookie);
		}
		//removing doubles from array if they exist
		check_with_cookie = TagChooser.cleanUpTagText(check_with_cookie);

		// if cookie is set, we are getting difference between current tags and saved ones
		if(recently_used_tags != null) {
			if (check_with_cookie != false && check_with_cookie != null && check_with_cookie != "") {
				recently_used_tags = TagChooser.cleanUpTagText(recently_used_tags);
				output = TagChooser.getTagDiff(check_with_cookie, recently_used_tags);
				// Logger.log("diff with cookie: " +output);
				output = TagChooser.cleanUpTagText(output);
				// summarizing output with previous cookie values
				recently_used_tags = output + ' ' + recently_used_tags;
				// Logger.log("new recent tags full list: " + recently_used_tags);
				recently_used_tags = TagChooser.getLastNumTagsReverse(TagChooser.recent_tags_save_amount, recently_used_tags);
				// Logger.log("cut recent tags list: " + recently_used_tags);
				if(recently_used_tags != false && recently_used_tags != null) {
					setCookie(TagChooser.recent_tags_cookie_name, recently_used_tags, "", "/", ".fotki.com");
				}
			}
		} else {
			output = TagChooser.getLastNumTagsReverse(TagChooser.recent_tags_save_amount, data);
			output = TagChooser.cleanUpTagText(output);
			if (output != null) {
				setCookie(TagChooser.recent_tags_cookie_name, output, "", "/", "." + fotki_hostname);
			}
		}
	}
}

TagChooser.getLastNumTags = function TagChooser_getLastNumTags (num, tag_text) {
	if (tag_text == null || tag_text == "") {
		return null;
	}
	var tags_array = tag_text.split(" ");
	var output_text = "";
	var i = tags_array.length-1;
	var limit_num = (tags_array.length-1)-num;
	// Logger.log(limit_num);
	for (i < tags_array.length; i > limit_num; --i) {
		if(tags_array[i] != "" && tags_array[i] != null) {
			output_text += ' ' +(tags_array[i]);
		}
	}
	if(output_text.length < 1) {
		return null;
	}
	return output_text;
}

TagChooser.getLastNumTagsReverse = function TagChooser_getLastNumTagsReverse(num, tag_text) {
	if (tag_text == null || tag_text == "") {
		return null;
	}
	var tags_array = tag_text.split(" ");
	var output_text = "";
	var i = 0;
	num++;
	for (i > 0; i < num; i++) {
		if(tags_array[i] != "" && tags_array[i] != null && tags_array[i] != "null") {
			output_text += ' ' +(tags_array[i]);
		}
	}
	if(output_text.length < 1) {
		return null;
	}
	return output_text;
}

TagChooser.getRecentTagsString =function () {
	var recent_tags =  getCookie(TagChooser.recent_tags_cookie_name);
	return TagChooser.cleanUpTagText(recent_tags);
}

TagChooser.convertTagsStringToHTML = function TagChooser_convertTagsStringToHTML(tag_string) {
	if (tag_string == null || tag_string == "") {
		return null;
	}
	var tags_array = tag_string.split(" ");
	var output_text = "";
	var y = 0;
	for (y > 0; y < tags_array.length; y++) {
		if(tags_array[y] != "" && tags_array[y] != null && tags_array[y] != "null") {
//tag limit checking feature: to be implemented soon
//			output_text += ' <span id="tag-' + Core.unescape(tags_array[y]) +'" class="tag"><a href="javascript:TagChooser.tagIt(\'' + Core.unescape(tags_array[y]) +'\');checkTagLimit();">' + Core.unescape(tags_array[y]) +'</a></span>';
			output_text += '<a href="javascript:TagChooser.tagIt(\'' + Core.unescape(tags_array[y]) +'\')" id="tag-' + Core.unescape(tags_array[y]) +'">' + Core.unescape(tags_array[y]) +'</a> ';
		}
	}
	if(output_text.length < 1) {
		return null;
	}
	output_text += '<a href="javascript:clearRecentTags()" class="button text5">clear</a>';
	return output_text;

}

TagChooser.clearRecentTagsList = function TagChooser_clearRecentTagsList() {
	setCookie(TagChooser.recent_tags_cookie_name, "", "", "/", "." + fotki_hostname);
}

TagChooser.getNumberOfTagsFromString = function TagChooser_getNumberOfTagsFromString(tags_string) {
   tags_string = tags_string.replace(/^\s+|\s+$/g, '');
   tags_string = tags_string.replace(/\s+/g, ' ');
   tags_array = tags_string.split(' ');
   return tags_array.length;
}

TagChooser.blockTagAdding = function TagChooser_blockTagAdding() {
	if(TagChooser.isTagFieldSet()) {
      return (TagChooser.getNumberOfTagsFromString(TagChooser.tag_field.value) >= TagChooser.max_tags_allowed) ? true : false;
   } else {
      return false;
   }
}
