/////////////
// General
/////////////

//var isDevMode;
var myDomain = null; // initialized in main.jsp
var isIe = null; // initialized in main.jsp
var isEmbed = null; // initialized in main.jsp
var isHeb = null; // initialized in main.jsp
var language = null; // initialized in main.jsp
var isPreselectedTags = null;
var loadingCounter = 0;
var authorizedFunction;
var categories = null;
var tags = null; //TODO: remove it (redundant)
var categoryIdToCategory = new Hash();
var categoryIdToTags = new Hash();
var tagIdToTag = new Hash();
var tagIdToTagCount = new Hash();
var items = null;
var itemIdToItem = new Hash();
var itemsTotalCount = null;
var categoryIdToTagsCountList = null; // [catId, {tagId:x, count:y}, {tagId:a, count:b}, ...]
var newItem = new Item({});
var imageSearch = null;
var myStatus = new Status({});
var user = null;
var moreActionsRelevantItemId = null;
var testUrl = null;
var menuItemSelected = "events";
var currentCalendarsUrl = null;
var completedInitTags = false;
var itemInDialog = null;
var isItemDialogOpened = null;
var recommendedItem = null;
var randomItem = null;
var hasNextRandomItem = null;
var hasPrevRandomItem = null;
var calendarNumOfWeeks = null;
var weekDaysNames = new Array(hMessages.getMessage('i18n.114'), hMessages.getMessage('i18n.115'), hMessages.getMessage('i18n.116'), hMessages.getMessage('i18n.117'), hMessages.getMessage('i18n.118'), hMessages.getMessage('i18n.119'), hMessages.getMessage('i18n.120'));
var monthsNames = new Array(hMessages.getMessage('i18n.121'), hMessages.getMessage('i18n.122'), hMessages.getMessage('i18n.123'), hMessages.getMessage('i18n.124'), hMessages.getMessage('i18n.125'), hMessages.getMessage('i18n.126'), hMessages.getMessage('i18n.127'), hMessages.getMessage('i18n.128'), hMessages.getMessage('i18n.129'), hMessages.getMessage('i18n.130'), hMessages.getMessage('i18n.131'), hMessages.getMessage('i18n.132'));
var initMethod = null;
var calendarView = null;
var TITLE_MAX_LENGTH = 60;
var DESC_MAX_LENGTH = 350;


// domains color
var domainColor20 = "A32929";
var domainColor22 = "2952A3";
var domainColor24 = "0D7813";
var domainColor25 = "8D6F47";
var domainColor39 = "393939";

function reloadPage(){
    location = myDomain;
}

function isNull(obj){
    return !isNotNull(obj);
}

function isNotNull(obj){
    return (obj != undefined && obj != null);
}

function isEmpty(obj){
    return (obj == undefined || obj == null || obj == "");
}

function isNotEmpty(obj){
    return !isEmpty(obj);
}

String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
};

function getSelectedOption(selectObjId){
    var selectObj = $(selectObjId);
    return selectObj.options[selectObj.selectedIndex];
}

function setSelectedOption(selectObjId, index){
    var selectObj = $(selectObjId);
    return selectObj.options[index].selected = true;
}

function getSelectedRadioElement(buttonGroup){
    if (buttonGroup[0]) {
        for (var i=0; i<buttonGroup.length; i++){
            if (buttonGroup[i].checked) {
                return buttonGroup[i];
            }
        }
    } else {
        if (buttonGroup.checked){
            return 0;
        }
    }
    return -1;
}

function submitEnter(myMethod, e)
{
    var keycode;
    if (window.event) keycode = window.event.keyCode;
    else if (e) keycode = e.which;
    else return true;

    if (keycode == 13)
    {
        myMethod();
        return false;
    }
    else
        return true;
}


function ajaxRequest(url, params, onSuccessCallback){
    if (loadingCounter == 0){
        $('loading').show();
        //$('blockDiv').show();
    }
    loadingCounter++;
    new Ajax.Request(url, {
        method:       'post',
        parameters:   params + "&isAjax=true",
        asynchronous: true,
        onComplete: onAjaxCompleteCallback,
        onSuccess: onSuccessCallback,
        onFailure: onAjaxFailure
    });
}

function onAjaxFailure(t){
    errorMessageDialog.setBody({text: "OnFailure Ajax Request: " + t.responseText, height:400, width:800, isClosable:true});
    errorMessageDialog.setButtons();
    errorMessageDialog.show();
    $('blockDiv').hide();
    $('loading').hide();
}

function onAjaxCompleteCallback(){
    loadingCounter--;
    if (loadingCounter == 0){
        $('loading').hide();
        //$('blockDiv').hide();
    }
}

function delayActivePing(){
    setTimeout(ping, 1000*60*5); // ping every 5 minutes
}

function ping(){
    new Ajax.Request("ping", {
        method:       'post',
        asynchronous: true,
        onComplete: delayActivePing
    });
}

function autoSelectTextField(inputElement){
    if (isIe){
        var textRange = inputElement.createTextRange();
        textRange.moveStart("character", 0);
        textRange.moveEnd("character", inputElement.value.length-1);
        textRange.select();
    } else {
        inputElement.selectionStart = 0;
        inputElement.selectionEnd = inputElement.value.length;
    }
}


function sdEscape(s){
    if (s == null){
        return null;
    } else {
        return s.replace(/-/g, "kkkhyphenkkk").replace(/&/g, "kkkampersandkkk").replace(/%/g, "kkkpercentkkk").replace(/#/g, "kkknumbersignkkk").replace(/\?/g, "kkkquestionmarkkkk").replace(/'/g, "kkkapostrophekkk").replace(/\r\n/g, "kkknewlinekkk").replace(/\n/g, "kkknewlinekkk").replace(/<script>/g, "#script#").replace(/<\/script>/g, "#script#");
    }
}

function flickerElement(elementId){
    setTimeout('makeInvisible(' + elementId + ')', 200);
    setTimeout('makeVisible(' + elementId + ')', 500);
    setTimeout('makeInvisible(' + elementId + ')', 700);
    setTimeout('makeVisible(' + elementId + ')', 1000);
}

function makeInvisible(elementId){
    $(elementId).style.visibility = 'hidden';
}

function makeVisible(elementId){
    $(elementId).style.visibility = 'visible';
}

/////////////
// Handlers
/////////////

function onTabClick(selectedTabId, otherTabId){
    $(selectedTabId).className = 'selectedTab';
    $(selectedTabId).down('table').style.display = "block";
    $(otherTabId).className = 'unselectedTab';
    $(otherTabId).down('table').style.display = "none";
}

function onTabOversideMenuTabs(tabElement){
    tabElement.style.backgroundColor= 'white';
}

function onTabOutsideMenuTabs(tabElement, isSelectedTab){
    tabElement.style.backgroundColor = (isSelectedTab) ? 'white': '#f1f1f1';
}

function onItemOver(id){
    $('itemMain' + id).parentNode.parentNode.parentNode.style.backgroundColor = "#f5f5f5";
    $("title" + id).style.backgroundColor = "#f5f5f5";
    $("text" + id).style.backgroundColor = "#f5f5f5";
    var item = isItemDialogOpened ? itemInDialog : itemIdToItem.get(id);
    if (isNotNull(user) && (user.role == "admin" || user.id == item.creatorId)){
        $("moreActionsButtonTd" + id).style.visibility = "visible";
    }
    $("facebookButtonTd" + id).style.visibility = "visible";
    $("linkButtonTd" + id).style.visibility = "visible";
}

function onItemOut(id){
    $('itemMain' + id).parentNode.parentNode.parentNode.style.backgroundColor = "";
    $("title" + id).style.backgroundColor = "";
    $("text" + id).style.backgroundColor = "";
    $("moreActionsButtonTd" + id).style.visibility = "hidden";
    $("facebookButtonTd" + id).style.visibility = "hidden";
    $("linkButtonTd" + id).style.visibility = "hidden";
}

function onLinkOver(menuItemId){
    $(menuItemId).style.textDecoration = 'underline';
}

function onLinkOut(menuItemId){
    $(menuItemId).style.textDecoration = 'none';
}

function onRecommendationOver(id){
    $("likeItButtonTd" + id).down("img", 0).style.display = "block";
    $("likeItButtonTd" + id).down("img", 1).style.display = "none";
    $("likeItButtonTd" + id).down("div").style.display = "none";
    if (isIe){
        $("likeItButtonTd" + id).down("div").style.right = "42px";
        $("likeItButtonTd" + id).down("div").style.paddingRight = "9px";
    } else {
        $("likeItButtonTd" + id).down("div").style.paddingRight = "12px";
    }
}

function onRecommendationOut(id){
    $("likeItButtonTd" + id).down("img", 0).style.display = "none";
    $("likeItButtonTd" + id).down("img", 1).style.display = "block";
    $("likeItButtonTd" + id).down("div").style.display = "block";
}


function changeTextToInput(myInput){
    myInput.className = '';
}

function changeInputToText(myInput){
    myInput.className = 'inputAsText';
}

function onCategoryOver(myImage){
    myImage.style.borderBottom= '3px solid #888888';
}

function onCategoryOut(myImage){
    myImage.style.borderBottom = '';
}

function isLinksMode(){
    return ("content" == menuItemSelected);
}

//////////////////////
// Menu
//////////////////////

function selectMenuItem(menuId){
    if (menuId == "content"){
        $('itemsDiv').show();
        $('calendarDiv').hide();
        $('contentDiv').show();
        menuItemSelected = 'content';
        myStatus.mode = 'content';
    } else if (menuId == "events"){
        $('itemsDiv').hide();
        $('calendarDiv').show();
        $('contentDiv').hide();
        menuItemSelected = 'events';
        myStatus.mode = 'events';
    }

    // when changing mode -> clear mode-specific category from filter
    if (isNotNull(categories)){
        for (var i=0; i<categories.size(); i++){
            if (categories[i].mode != 'all'){
                if (isNotNull(myStatus.clearCategorySelection)){
                    myStatus.clearCategorySelection(categories[i].id);
                }
            }
        }
        repaintFilterToolbar();
    }

    updateMainToolbar();
    reloadItems();
}

/////////////////////////
// Init
/////////////////////////

function initSocialDev()
{
    loadInitData(); // onCompleteInitData calls selectMenuItem which calls in its turn to reloadItems
    updateMainToolbar();
    initCalendar();
    $('body').observe('click', onBodyClick);
    postInit();
    delayActivePing();
}

function loadInitData(){
    var url = 'loadInitData';
    ajaxRequest(url, null, onCompleteLoadInitData);
}

function onCompleteLoadInitData(res){
    var response = eval("(" + res.responseText + ")");

    // user
    if (isEmpty(response.user)){
        user = null;
    } else {
        user = response.user;
    }
    renderUserPane();

    // categories
    categories = response.categories;
    for (var i=0; i<categories.size(); i++){
        categoryIdToCategory.set(categories[i].id, categories[i]);
        categoryIdToTags.set([categories[i].id], new Array());
    }

    tags = response.tags;
    for (i=0; i<tags.size(); i++){
        categoryIdToTags.get([tags[i].categoryId]).push(tags[i]);
        tagIdToTag.set(tags[i].id,  tags[i]);
    }
    completedInitTags = true;

    // recommended item
    recommendedItem = response.recommendedItem;

    // init method
    if (isNotEmpty(response.initMethod)){
        initMethod = response.initMethod;
    }

    // pre-selected tags
    if (isNotEmpty(location.search.toLowerCase().indexOf("tags=") != -1)){
        var preselectedTagsParameter = location.search.substring(location.search.toLowerCase().indexOf("tags=") + "tags=".length);
        isPreselectedTags = true;
        var preselectedTags = preselectedTagsParameter.split(",");
        for (i=0; i<preselectedTags.length; i++){
            myStatus.addSelectedTag(tagIdToTag.get(preselectedTags[i]).categoryId, Number(preselectedTags[i]));
        }
    }

    // unsubscribe
    if (isNotEmpty(response.unsubscribeEmail)){
        var unsubscribeEmail = response.unsubscribeEmail;
        openUnsubscribeDialog(unsubscribeEmail);
    }

    // selected item
    if (isNotEmpty(response.selectedItem)){
        var selectedItem = response.selectedItem;
        openItemDialog(selectedItem);
        selectMenuItem(selectedItem.type == "content" ? selectedItem.type : "events");
    } else {
        selectMenuItem('events');
    }
}

function postInit(){
    if (loadingCounter == 0){
        // call method in queryString
        if (isNotEmpty(initMethod)){
            eval(initMethod + "()");
        }
        hideBigLoading();
    } else {
        setTimeout(postInit, 100);
    }
}

function showBigLoading(){
    $('bigLoading').style.display = 'block';
}

function hideBigLoading(){
    $('bigLoading').style.display = 'none';
}

/////////////////////////
// Main Toolbar
/////////////////////////

function updateMainToolbar(){
    $('eventsTab').style.marginLeft = "0";
    $('contentTab').style.marginRight = "0";

    if (isLinksMode()){
        $('eventsTabActions').hide();
        $('contentTabActions').show();
        $('eventsTab').className = "unselectedTabBig";
        $('contentTab').className = "selectedTabBig";
        $('eventsTab').style.marginLeft = "-1px";
    } else {
        $('eventsTabActions').show();
        $('contentTabActions').hide();
        $('eventsTab').className = "selectedTabBig";
        $('contentTab').className = "unselectedTabBig";
        $('contentTab').style.marginRight = "-1px";
    }
}

/////////////////////////
// Submit New Item
/////////////////////////

function openContentDialog(){
    selectMenuItem("content");
    openShareDialog("content");
}

function openEventDialog(){
    selectMenuItem("events");
    openShareDialog("event");
}

function openShareDialog(type){
    newItem = new Item({});
    var htmlString = submitLinkHtml.replace(/shareDialogLabelPlaceholder/, type == 'content' ? hMessages.getMessage('i18n.94') : hMessages.getMessage('i18n.95'));
    if (isEmbed){
        submitLinkDialog.setBody({text: htmlString, width: 500, isClosable:true});
    }else {
        submitLinkDialog.setBody({text: htmlString, width: 600, isClosable:true});
    }
    if (type == 'event'){
        $('eventFields').show();
    }
    submitLinkDialog.setButtons({caption:hMessages.getMessage('i18n.105'), onclick: onSubmitLink}, {caption:hMessages.getMessage('i18n.106'), onclick: submitLinkDialog.hide});
    submitLinkDialog.show();    
    newItem.type = type;
    if (isNotNull(testUrl)){
        $('newLink').value = testUrl;
    }
    onChangeTitle();
    onChangeDescription();
    submitLinkDialog.repaint();
}

function askDataForLink(myLink){
    ajaxRequest("loadLinkData", 'link='+sdEscape(myLink), onCompleteDataForLink);
    $('blockDiv').show();
}

function onCompleteDataForLink(res){
    $('blockDiv').hide();
    $('linkDetailsDiv').style.display = "block";
    var response = res.responseText;
    $('linkTitle').value = response.substring('linkTitleBegin'.length+1, response.indexOf('linkTitleEnd'));
    if (isEmpty($('linkTitle').value)){
        $('linkTitle').className = "";
    }
    $('linkDescription').value = response.substring(response.indexOf('linkDescriptionBegin')+'linkDescriptionBegin'.length, response.indexOf('linkDescriptionEnd'));
    if (isEmpty($('linkDescription').value)){
        $('linkDescription').className = "";
    }

    // retreive the images
    var suggestedImages = new Array();
    var baseIndex=0;
    var i = 0;
    while(true){
        var beginIndex = response.indexOf('linkImageBegin', baseIndex)+'linkImageBegin'.length;
        var endIndex = response.indexOf('linkImageEnd', baseIndex+1);
        var image = response.substring(beginIndex, endIndex);

        if (endIndex == -1){
            break;
        } else {
            suggestedImages[i++] = image;
            baseIndex = endIndex + 1;
        }
    }
    newItem.suggestedImagesIndex = 0;
    newItem.googleImagesIndex = 0;

    // set the first image at the front
    if (suggestedImages.size() > 0){
        Event.observe('linkImage', 'load', onFirstImageReady);
        $('linkImage').src = suggestedImages[0];
    }

    newItem.importData();
    newItem.suggestedImages = suggestedImages;
    submitLinkDialog.repaint();
}

function onFirstImageReady(){
    submitLinkDialog.repaint();
}

function openImageSelectionDialog(){
    newItem.importData();
    selectImageDialog.setBody({text: selectImageHtml, width: 580, height: 400, isClosable:true});
    renderSuggestedImages();
    $('imageGoogleSearchField').value = newItem.title;
    executeGoogleSearch();
    selectImageDialog.show();
}

function renderSuggestedImages(){
    $('suggestedImagesDiv').innerHTML = "";
    var i = newItem.suggestedImagesIndex;
    var j = 0;
    while(i < newItem.suggestedImages.size() && j < 4){
        $('suggestedImagesDiv').innerHTML += "<img class='edittedItemImage' style='cursor:pointer;' onclick='onSelectImage(this); this.blur();' src='" + newItem.suggestedImages[i] + "'>";
        i++; j++;
    }

    if (i > 4){
        $('previousImagesArrow').style.visibility = "visible";
    } else {
        $('previousImagesArrow').style.visibility = "hidden";
    }

    if (i < (newItem.suggestedImages.size())){
        $('nextImagesArrow').style.visibility = "visible";
    } else {
        $('nextImagesArrow').style.visibility = "hidden";
    }
}

function goPreviousImages(){
    newItem.suggestedImagesIndex -= 4;
    if (newItem.suggestedImagesIndex < 0){
        newItem.suggestedImagesIndex = 0;
    }
    renderSuggestedImages();
}

function goNextImages(){
    newItem.suggestedImagesIndex += 4;
    renderSuggestedImages();
}

function executeGoogleSearch() {
    var searchPhrase = $('imageGoogleSearchField').value;
    if (searchPhrase.startsWith("http://")){
        newItem.image = searchPhrase;
        selectImageDialog.hide();
        newItem.exportData();
        submitLinkDialog.repaint();
    } else {
        newItem.googleImagesIndex = 0;
        imageSearch = new google.search.ImageSearch();
        imageSearch.setSearchCompleteCallback(null, renderGoogleImages);
        imageSearch.setResultSetSize(google.search.Search.LARGE_RESULTSET);
        imageSearch.execute(searchPhrase);
    }
}

function renderGoogleImages(){
    if (imageSearch.results.size() > 0){
        $('googleSearchResultDiv').innerHTML = "";
        var i = newItem.googleImagesIndex;
        var j = 0;
        while(i < imageSearch.results.size() && j < 4){
            $('googleSearchResultDiv').innerHTML += "<img class='edittedItemImage' style='cursor:pointer;' onclick='onSelectImage(this); this.blur();' src='" + imageSearch.results[i].tbUrl + "'>";
            i++; j++;
        }

        if (i > 4){
            $('previousGoogleArrow').style.visibility = "visible";
        } else {
            $('previousGoogleArrow').style.visibility = "hidden";
        }

        if (i < (imageSearch.results.size())){
            $('nextGoogleArrow').style.visibility = "visible";
        } else {
            $('nextGoogleArrow').style.visibility = "hidden";
        }
    } else {
        $('googleSearchResultDiv').innerHTML += hMessages.getMessage('i18n.96');
    }
}

function goPreviousGoogleImages(){
    newItem.googleImagesIndex -= 4;
    if (newItem.googleImagesIndex < 0){
        newItem.googleImagesIndex = 0;
    }
    renderGoogleImages();
}

function goNextGoogleImages(){
    newItem.googleImagesIndex += 4;
    renderGoogleImages();
}

function onCancelImageSelection(){
    selectImageDialog.hide();
}

function onSelectImage(imgElement){
    newItem.image = imgElement.src;
    selectImageDialog.hide();
    newItem.exportData();
    submitLinkDialog.repaint();
}

function openTagsSelectionDialog(){
    newItem.importData();
    selectTagsDialog.setBody({text: selectTagsHtml, width: 500, height:330, isClosable:true});
    newItem.categoriesIndex = 0;
    renderTagsSelectionCurrentStep();
    repaintSuggestedTagsSelection();
    repaintAccumulateSelectedTags();
    selectTagsDialog.show();
}

function goNextCategory(){
    newItem.categoriesIndex++;
    var categoryMode = categories[newItem.categoriesIndex].mode;
    if (categoryMode != 'all' && categoryMode != newItem.type){
        newItem.categoriesIndex++;
    }
    renderTagsSelectionCurrentStep();
    repaintSuggestedTagsSelection();
    repaintAccumulateSelectedTags();
}

function goPreviousCategory(){
    newItem.categoriesIndex--;
    var categoryMode = categories[newItem.categoriesIndex].mode;
    if (categoryMode != 'all' && categoryMode != menuItemSelected){
        newItem.categoriesIndex--;
    }
    renderTagsSelectionCurrentStep();
    repaintSuggestedTagsSelection();
    repaintAccumulateSelectedTags();
}

function renderTagsSelectionCurrentStep(){
    var category = categories[newItem.categoriesIndex];
    var categoryTags = categoryIdToTags.get(category.id);
    var tagsHtml = "<span class='label1' style =''>" + category.name + "</span>";
    if (category.editable){
        tagsHtml += "<div style='width:100%; height:180px; overflow-y:auto'>";
    }
    for (var i=0; i<categoryTags.size(); i++){
        tagsHtml += "<table cellpadding='0' cellspacing='0'><tr><td><img onclick='onSelectSuggestedTag(" + category.id + ", " + categoryTags[i].id + ", true);' style='cursor:pointer' id='suggestedTagCheckbox" + categoryTags[i].id + "' src='images/unchecked.png'></td><td style='padding-right:3px; white-space:nowrap'><span class='link' onclick='onSelectSuggestedTag(" + category.id + ", " + categoryTags[i].id + ", false);'>" + categoryTags[i].name + "</span></td></tr></table>";
    }
    if (category.editable){
        tagsHtml += "</div>";
        tagsHtml += "<br><span onclick='showSuggestTagField()' class='link' style='font-size:10px'>" + hMessages.getMessage('i18n.97') + "</span>";
        tagsHtml += "<table id='otherTag' style='display:none' ><tr><td style='font-size:10px'>" + hMessages.getMessage('i18n.98') + ":</td><td><input name='otherTagField' style='font-size:10px; height:16px; width:70px'></td><td><button onclick='sendSuggestedTag(" + category.id + ")' style='font-size:10px; height:16px; width:30px'>" + hMessages.getMessage('i18n.105') + "</button></td></tr></table>";
        tagsHtml += "<br><span style='font-size:10px; display:none' id='otherTagThankYou'>" + hMessages.getMessage('i18n.99') + "</span>";
    }
    renderTagsSelectionControlButtons();
    $('suggestedTags').innerHTML = tagsHtml;

    $('currentStep').innerHTML = 1 + newItem.categoriesIndex;
    $('totalSteps').innerHTML = categories.size();
}

function showSuggestTagField(){
    document.getElementsByName('otherTagField')[0].value = "";
    $('otherTag').show();
    $('otherTagThankYou').hide();
}

function sendSuggestedTag(categoryId){
    var suggestedTag = document.getElementsByName('otherTagField')[0].value;
    var url = 'suggestTag';
    var params = 'categoryId=' + categoryId + "&tagName=" + sdEscape(suggestedTag);
    ajaxRequest(url, params, onSuggestTagSuccess);
}

function onSuggestTagSuccess(){
    $('otherTag').hide();
    $('otherTagThankYou').show();
}

function renderTagsSelectionControlButtons(){
    var nextLabel = hMessages.getMessage('i18n.100') + " >>";
    var prevLabel = "<< " + hMessages.getMessage('i18n.101');
    var endLabel = hMessages.getMessage('i18n.102');
    if ((newItem.categoriesIndex+1) == categories.size()){
        newItem.reachedLastSuggestedTag = true;
        selectTagsDialog.setButtons({caption:prevLabel, onclick: goPreviousCategory}, {caption:endLabel, onclick: onSelectTagsForNewItem}, {caption:nextLabel, onclick: goNextCategory, disabled:true});
    } else if ((newItem.categoriesIndex) == 0){
        if (newItem.reachedLastSuggestedTag){
            selectTagsDialog.setButtons({caption:prevLabel, onclick: goPreviousCategory, disabled:true}, {caption:endLabel, onclick: onSelectTagsForNewItem}, {caption:nextLabel, onclick: goNextCategory});
        } else {
            selectTagsDialog.setButtons({caption:prevLabel, onclick: goPreviousCategory, disabled:true}, {caption:endLabel, onclick: onSelectTagsForNewItem, disabled:true}, {caption:nextLabel, onclick: goNextCategory});
        }
    } else {
        if (newItem.reachedLastSuggestedTag){
            selectTagsDialog.setButtons({caption:prevLabel, onclick: goPreviousCategory}, {caption:endLabel, onclick: onSelectTagsForNewItem}, {caption:nextLabel, onclick: goNextCategory});
        } else {
            selectTagsDialog.setButtons({caption:prevLabel, onclick: goPreviousCategory}, {caption:endLabel, onclick: onSelectTagsForNewItem, disabled:true}, {caption:nextLabel, onclick: goNextCategory});
        }
    }
}

function onSelectSuggestedTag(categoryId, tagId, isToggle){
    // if user clicked on a checkbox
    if (isNotNull(isToggle) && isToggle){
        var isTagSelected = newItem.isTagSelected(categoryId, tagId);
        if (isTagSelected){
            newItem.clearTagSelection(categoryId, tagId);
        } else {
            newItem.addSelectedTag(categoryId, tagId);
        }
        // if user clicked on a tag name
    } else {
        newItem.setSelectedTag(categoryId, tagId);
    }

    repaintSuggestedTagsSelection();
    repaintAccumulateSelectedTags();

}

function repaintSuggestedTagsSelection(){
    var categoryId = categories[newItem.categoriesIndex].id;
    var allCategoryTags = categoryIdToTags.get(categoryId);
    var selectedCategoryTagsIds = newItem.categoryIdToSelectedTags.get(categoryId);
    var selectedTags = new Hash();
    var unselectedTags = new Hash();
    for (var i=0; i<allCategoryTags.size(); i++){
        unselectedTags.set(allCategoryTags[i].id, allCategoryTags[i].id);
    }
    if (isNotNull(selectedCategoryTagsIds)){
        for (i=0; i<selectedCategoryTagsIds.size(); i++){
            selectedTags.set(selectedCategoryTagsIds[i], selectedCategoryTagsIds[i]);
            unselectedTags.unset(selectedCategoryTagsIds[i]);
        }
    }
    selectedTags.each(function(pair){
        $('suggestedTagCheckbox' + pair.key).src = "images/checked.png";
    });
    unselectedTags.each(function(pair){
        $('suggestedTagCheckbox' + pair.key).src = "images/unchecked.png";
    });
}

function repaintAccumulateSelectedTags(){
    var selectedTagsHtml = "";
    newItem.categoryIdToSelectedTags.each(function (pair){
        var categoryId = pair.key;
        var selectedTagsIds = pair.value;
        selectedTagsHtml += "<span class='label1' style =''>" + categoryIdToCategory.get(categoryId).name + "</span><br>";
        for (var i=0; i<selectedTagsIds.size(); i++){
            var selectedTag = tagIdToTag.get(selectedTagsIds[i]);
            selectedTagsHtml += "<span class='link' onclick='onRemoveTag(" + categoryId + ", " + selectedTag.id + ");'>" + selectedTag.name + "</span><br>";
        }
    });
    $('selectedTags').innerHTML = selectedTagsHtml;
}

function onRemoveTag(categoryId, tagId){
    newItem.clearTagSelection(categoryId, tagId);
    repaintAccumulateSelectedTags();
}

function onSelectTagsForNewItem(){
    newItem.exportData();
    selectTagsDialog.hide();
}

function openItemAdditionalLinksDialog(){
    itemAdditionalLinksDialog.setBody({text: itemAdditionalLinksHtml});
    itemAdditionalLinksDialog.setButtons({caption:hMessages.getMessage('i18n.159'), onclick: updateItemAdditionalLinks}, {caption:hMessages.getMessage('i18n.106'), onclick: itemAdditionalLinksDialog.hide});
    if (isNotEmpty(newItem.facebook)){
        $('facebookLink').value = newItem.facebook;
    }
    if (isNotEmpty(newItem.wikipedia)){
        $('wikipediaLink').value = newItem.wikipedia;
    }
    itemAdditionalLinksDialog.show();
}

function updateItemAdditionalLinks(){
    if ($('facebookLink').value != "http://"){
        newItem.facebook = $('facebookLink').value;
    }
    if ($('wikipediaLink').value != "http://"){
        newItem.wikipedia = $('wikipediaLink').value;
    }
    itemAdditionalLinksDialog.hide();
}

function onSubmitLink(){
    if (isNull(user)){
        openLoginDialog();
        authorizedFunction = onSubmitLink;
    } else {
        newItem.importData();
        if (newItem.isValid()){
            var url = 'addItem';
            var params = 'jsonItem=' + newItem.toJSON();
            $('blockDiv').show();
            ajaxRequest(url, params, onSubmitLinkSuccess);
        } else {

        }
    }
}

function onSubmitLinkSuccess(){
    reloadItems();
    submitLinkDialog.hide();
    $('blockDiv').hide();
    thankyouDialog.setBody({text: thankYouDialogHtml, isClosable:true});
    thankyouDialog.setButtons({caption:hMessages.getMessage('i18n.102'), onclick: thankyouDialog.hide});
    thankyouDialog.show();
}


///////////////
// Edit Item
///////////////

function openEditItem(itemId){
    var item = null;
    if (isNotNull(itemInDialog)){
        item = itemInDialog;
    } else {
        item = itemIdToItem.get(itemId);
    }
    if (isNull(user)){
        openLoginDialog();
        authorizedFunction = openEditItem;
    } else {
        var htmlString = submitLinkHtml.replace(/shareDialogLabelPlaceholder/, item.type == "content" ? hMessages.getMessage('i18n.103') : hMessages.getMessage('i18n.104'));
        submitLinkDialog.setBody({text: htmlString, width: 600, isClosable:true});
        if (!isLinksMode()){
            $('eventFields').show();
        }
        submitLinkDialog.setButtons({caption:hMessages.getMessage('i18n.105'), onclick: onSubmitLink}, {caption:hMessages.getMessage('i18n.106'), onclick: submitLinkDialog.hide});
        newItem.fromJSON(item);
        newItem.exportData();
        $('linkDetailsDiv').style.display = "block";
        submitLinkDialog.show();
    }
}

function onChangeTitle(){
    var charsCount = $('linkTitle').value.length;
    var gap = TITLE_MAX_LENGTH - charsCount;
    if (gap >= 0){
        $('itemTitleMessage').innerHTML = hMessages.getMessage('i18n.107') + " " + gap + " " + hMessages.getMessage('i18n.108');
                $('itemTitleMessage').style.color = "#999";
    } else {
        $('itemTitleMessage').innerHTML = hMessages.getMessage('i18n.109') + Math.abs(gap) + " " + hMessages.getMessage('i18n.108');
        $('itemTitleMessage').style.color = "red";
    }
}

function onChangeDescription(){
    var charsCount = $('linkDescription').value.length;
    var gap = DESC_MAX_LENGTH - charsCount;
    if (gap >= 0){
        $('itemDescMessage').innerHTML = hMessages.getMessage('i18n.107') + " " + gap + " " + hMessages.getMessage('i18n.108');
                $('itemDescMessage').style.color = "#999";
    } else {
        $('itemDescMessage').innerHTML = hMessages.getMessage('i18n.109') + Math.abs(gap) + " " + hMessages.getMessage('i18n.108');
        $('itemDescMessage').style.color = "red";
    }
}

/////////////
// Item
/////////////

function Item(jsonObj){

    var _this = this;
    _this.id = null;
    _this.type = null;
    _this.link = null;
    _this.wikipedia = null;
    _this.facebook = null;
    _this.title = null;
    _this.description = null;
    _this.image = null;
    _this.imageType = null;
    _this.suggestedImages = new Array();
    _this.categoriesIndex = 0;
    _this.categoryIdToSelectedTags = null;
    _this.reachedLastSuggestedTag = false;
    _this.creationTime = null;
    _this.suggestedImagesIndex = null;
    _this.googleImagesIndex = null;
    _this.approved = null;
    _this.recommend = null;
    _this.recommendations = null;
    _this.domainIds = null; // read only

    _this.location = null;
    _this.fromYear = null;
    _this.fromMonth = null;
    _this.fromDay = null;
    _this.fromHour = null;
    _this.fromMinutes = null;
    _this.toYear = null;
    _this.toMonth = null;
    _this.toDay = null;
    _this.toHour = null;
    _this.toMinutes = null;
    _this.formattedFromTo = null; // read only

    _this.fromJSON = function(jsonObj){
        _this.id = (isNotNull(jsonObj.id) ? jsonObj.id : null);
        _this.type = (isNotNull(jsonObj.type) ? jsonObj.type : null);
        _this.language = language;
        _this.link = (isNotNull(jsonObj.link) ? jsonObj.link : null);
        _this.wikipedia = (isNotNull(jsonObj.wikipedia) ? jsonObj.wikipedia : null);
        _this.facebook = (isNotNull(jsonObj.facebook) ? jsonObj.facebook : null);
        _this.title = (isNotNull(jsonObj.title) ? jsonObj.title : null);
        _this.description = (isNotNull(jsonObj.description) ? jsonObj.description : null);
        _this.image = (isNotNull(jsonObj.image) ? jsonObj.image : null);
        _this.imageType = (isNotNull(jsonObj.imageType) ? jsonObj.imageType : 'url');
        _this.creationTime = (isNotNull(jsonObj.creationTime) ? jsonObj.creationTime : 0);
        _this.categoriesIndex = 0;
        _this.reachedLastSuggestedTag = false;
        _this.approved = (isNotNull(jsonObj.approved) ? jsonObj.approved : null);
        _this.recommend = (isNotNull(jsonObj.recommend) ? jsonObj.recommend : null);
        _this.recommendations = (isNotNull(jsonObj.recommendations) ? jsonObj.recommendations : null);
        _this.domainIds = (isNotNull(jsonObj.domainIds) ? jsonObj.domainIds : null);

        _this.location = (isNotNull(jsonObj.location) ? jsonObj.location : null);
        _this.fromYear = (isNotNull(jsonObj.fromYear) ? jsonObj.fromYear : null);
        _this.fromMonth = (isNotNull(jsonObj.fromMonth) ? jsonObj.fromMonth : null);
        _this.fromDay = (isNotNull(jsonObj.fromDay) ? jsonObj.fromDay : null);
        _this.fromHour = (isNotNull(jsonObj.fromHour) ? jsonObj.fromHour : null);
        _this.fromMinutes = (isNotNull(jsonObj.fromMinutes) ? jsonObj.fromMinutes : null);
        _this.toYear = (isNotNull(jsonObj.toYear) ? jsonObj.toYear : null);
        _this.toMonth = (isNotNull(jsonObj.toMonth) ? jsonObj.toMonth : null);
        _this.toDay = (isNotNull(jsonObj.toDay) ? jsonObj.toDay : null);
        _this.toHour = (isNotNull(jsonObj.toHour) ? jsonObj.toHour : null);
        _this.toMinutes = (isNotNull(jsonObj.toMinutes) ? jsonObj.toMinutes : null);
        _this.formattedFromTo = (isNotNull(jsonObj.formattedFromTo) ? jsonObj.formattedFromTo : null);

        _this.categoryIdToSelectedTags = new Hash();
        for (var key in jsonObj.categoryIdToSelectedTags){
            _this.categoryIdToSelectedTags.set(key, jsonObj.categoryIdToSelectedTags[key]);
        }
    };

    _this.toJSON = function(){
        var result = "{id:" +_this.id + ", " +
                     "link:'" + (sdEscape(_this.link)) + "', " +
                     "wikipedia:" + (isNull(_this.wikipedia) ? null : "'" + sdEscape(_this.wikipedia) + "'") +  ", " +
                     "facebook:" + (isNull(_this.facebook) ? null : "'" + sdEscape(_this.facebook) + "'") +  ", " +
                     "type:'" + (sdEscape(_this.type)) + "', " +
                     "language:'" + (sdEscape(_this.language)) + "', " +
                     "title:'" + (sdEscape(_this.title)) + "', " +
                     "description:'" + (sdEscape(_this.description)) + "', " +
                     "image:'" + (sdEscape(_this.image)) + "', " +
                     "imageType:'" + (sdEscape(_this.imageType)) + "', " +
                     "approved:" + _this.approved + ", " +
                     "recommend:" + _this.recommend + ", " +
                     "recommendations:" + _this.recommendations + ", " +
                     "categoryIdToSelectedTags:" + (isNotNull(_this.categoryIdToSelectedTags) ? _this.categoryIdToSelectedTags.toJSON() : null) + ", " +
                     "creationTime:" + _this.creationTime + ", " +
                     "location:'" + (sdEscape(_this.location)) + "', " +
                     "fromYear:'" + (sdEscape(_this.fromYear)) + "', " +
                     "fromMonth:'" + _this.fromMonth + "', " +
                     "fromDay:'" + (sdEscape(_this.fromDay)) + "', " +
                     "fromHour:'" + (sdEscape(_this.fromHour)) + "', " +
                     "fromMinutes:'" + (sdEscape(_this.fromMinutes)) + "', " +
                     "toYear:'" + (sdEscape(_this.toYear)) + "', " +
                     "toMonth:'" + _this.toMonth + "', " +
                     "toDay:'" + (sdEscape(_this.toDay)) + "', " +
                     "toHour:'" + (sdEscape(_this.toHour)) + "', " +
                     "toMinutes:'" + (sdEscape(_this.toMinutes)) + "'" +
                     "}";
        return result;
    };

    _this.isValid = function(){
        var isTitleValid = true;
        if ($('linkTitle').value.length > TITLE_MAX_LENGTH){
            isTitleValid = false;
        } else if ($('linkTitle').value.length == 0) {
            $('itemTitleMessage').style.color = 'red';
            $('itemTitleMessage').innerHTML = hMessages.getMessage('i18n.110');
            isTitleValid = false;
        }
        if (!isTitleValid){
            flickerElement('itemTitleMessage');
        }

        var isDescValid = true;
        if ($('linkDescription').value.length > DESC_MAX_LENGTH){
            isDescValid = false;
        } else if ($('linkDescription').value.length == 0) {
            $('itemDescMessage').style.color = 'red';
            $('itemDescMessage').innerHTML = hMessages.getMessage('i18n.111');
            isDescValid = false;
        }
        if (!isDescValid){
            flickerElement('itemDescMessage');
        }

        return isTitleValid && isDescValid;
    };

    _this.clear = function(){
        _this.fromJSON({});
    };

    _this.importData = function(){
        _this.link = $('newLink').value;
        _this.title = $('linkTitle').value;
        _this.description = $('linkDescription').value;
        _this.image = $('linkImage').src;

        if (_this.type == 'event'){
            _this.location = $('eventLocation').value;
            _this.fromYear = getSelectedOption('eventFromYear').innerHTML;
            _this.fromMonth = Number(getSelectedOption('eventFromMonth').innerHTML) - 1;
            _this.fromDay = "" + getSelectedOption('eventFromDay').innerHTML;
            _this.fromHour = "" + getSelectedOption('eventFromHour').innerHTML;
            _this.fromMinutes = "" + getSelectedOption('eventFromMinutes').innerHTML;
            _this.toYear = getSelectedOption('eventToYear').innerHTML;
            _this.toMonth = Number(getSelectedOption('eventToMonth').innerHTML) - 1;
            _this.toDay = "" + getSelectedOption('eventToDay').innerHTML;
            _this.toHour = "" + getSelectedOption('eventToHour').innerHTML;
            _this.toMinutes = "" + getSelectedOption('eventToMinutes').innerHTML;
        }
    };

    _this.exportData = function(){
        $('newLink').value = _this.link;
        $('linkTitle').value = _this.title;
        $('linkDescription').value = _this.description;
        $('linkImage').src = _this.image;

        if (_this.type == 'event'){
            $('eventLocation').value = _this.location;
            setSelectedOption('eventFromYear', Number(_this.fromYear)-2010);
            setSelectedOption('eventFromMonth', Number(_this.fromMonth));
            setSelectedOption('eventFromDay', Number(_this.fromDay)-1);
            setSelectedOption('eventFromHour', Number(_this.fromHour));
            setSelectedOption('eventFromMinutes', Number(_this.fromMinutes)/10);
            setSelectedOption('eventToYear', Number(_this.toYear)-2010);
            setSelectedOption('eventToMonth', Number(_this.toMonth));
            setSelectedOption('eventToDay', Number(_this.toDay)-1);
            setSelectedOption('eventToHour', Number(_this.toHour));
            setSelectedOption('eventToMinutes', Number(_this.toMinutes)/10);
        }

        $('theTags').innerHTML = "";
        _this.categoryIdToSelectedTags.each(function(pair){
            var category = categoryIdToCategory.get(pair.key);
            $('theTags').innerHTML += "<b>" + category.name + ":</b> ";
            var categoryTagsIds = pair.value;
            for (var i=0; i<categoryTagsIds.size(); i++){
                $('theTags').innerHTML += tagIdToTag.get(categoryTagsIds[i]).name;
                if (i == (categoryTagsIds.size()-1)){
                    $('theTags').innerHTML += "  ";
                } else {
                    $('theTags').innerHTML += ", ";
                }
            }
        });
        submitLinkDialog.repaint();
        onChangeTitle();
        onChangeDescription();
    };

    _this.setSelectedTag = function(categoryId, tagId){
        _this.categoryIdToSelectedTags.set(categoryId, [tagId]);
    };

    _this.addSelectedTag = function(categoryId, tagId){
        var tags = _this.categoryIdToSelectedTags.get(categoryId);
        if (isNull(tags)){
            _this.categoryIdToSelectedTags.set(categoryId, new Array());
        }
        _this.categoryIdToSelectedTags.get(categoryId).push(tagId);
    };

    _this.clearCategorySelection = function(categoryId){
        _this.categoryIdToSelectedTags.unset(categoryId);
    };

    _this.clearTagSelection = function(categoryId, tagId){
        var tags = _this.categoryIdToSelectedTags.get(categoryId);
        for (var i=0; i<tags.size(); i++){
            if (tags[i] == tagId){
                _this.categoryIdToSelectedTags.set(categoryId, tags.without(tagId));
                if (_this.categoryIdToSelectedTags.get(categoryId).size() == 0){
                    _this.clearCategorySelection(categoryId);
                }
            }
        }
    };

    _this.isTagSelected = function(categoryId, tagId){
        var tags = _this.categoryIdToSelectedTags.get(categoryId);
        if (isNotNull(tags)){
            for (var i=0; i<tags.size(); i++){
                if (tags[i] == tagId){
                    return true;
                }
            }
        }
        return false;
    };

    _this.fromJSON(jsonObj);
}

//////////////////////
// Categories
//////////////////////

function onClearCategory(categoryId){
    myStatus.clearCategorySelection(categoryId);
    myStatus.pageNum = 1;
    repaintTagsSelection();
    if (!isLinksMode()){
        paintCalendar();
    }
    ajaxRequest("loadItems", "status=" + myStatus.toJSON(), renderingItems);
}

//////////////////////
// Tags
//////////////////////

function onSelectTag(categoryId, tagId){
    $('tagsPane').show();
    var isTagSelected = myStatus.isTagSelected(categoryId, tagId);
    if (isTagSelected){
        myStatus.clearTagSelection(categoryId, tagId);
    } else {
        myStatus.setSelectedTag(categoryId, tagId);
    }
    myStatus.pageNum = 1;
    repaintTagsSelection();
    repaintFilterToolbar();
    if (!isLinksMode()){
        paintCalendar();
    }
    ajaxRequest("loadItems", "status=" + myStatus.toJSON(), renderingItems);

    if (categoryId == 1){
        /*$('domainLabel20').style.textDecoration = "none";
         $('domainLabel22').style.textDecoration = "none";
         $('domainLabel24').style.textDecoration = "none";
         $('domainLabel25').style.textDecoration = "none";*/
        if (!isTagSelected && isNotNull($('domainLabel' + tagId))){
            $('domainLabel' + tagId).style.textDecoration = "underline";
        }
    }
    if (isItemDialogOpened){
        generalDialog.hide();
    }
}

function repaintTagsSelection(){
    var selectedTags = new Hash();
    var unselectedTags = new Hash();
    categoryIdToTags.each(function(pair){
        if (categoryIdToCategory.get(pair.key).approved){
            var tags = pair.value;
            for (var i=0; i<tags.size(); i++){
                unselectedTags.set(tags[i].id, tags[i].id);
            }
        }
    })
    myStatus.categoryIdToSelectedTags.each(function(pair) {
        var tags = pair.value;
        for (var i=0; i<tags.size(); i++){
            selectedTags.set(tags[i], tags[i]);
            unselectedTags.unset(tags[i]);
        }
    });
    selectedTags.each(function(pair){
        if (isNotNull($('tag' + pair.key))){
            $('tag' + pair.key).style.color = getTagColor(tagIdToTag.get(pair.key), true);
            $('tag' + pair.key).style.fontWeight = "bold";
        }
    });
    unselectedTags.each(function(pair){
        if (isNotNull($('tag' + pair.key))){
            $('tag' + pair.key).style.color = getTagColor(tagIdToTag.get(pair.key), false);
            $('tag' + pair.key).style.fontWeight = "normal";
        }
    });
}

function repaintFilterToolbar(){
    var filterHtml = "";
    var filterEmpty = true;
    if (!myStatus.isFilterEmpty()){
        filterHtml += "<table align='right' cellpadding='0' cellspacing='0'><tr>";
        filterHtml += "<td style='font-weight:bold'>" + hMessages.getMessage('i18n.158') + ": </td>";
        categoryIdToCategory.each(function(pair){
            var category = pair.value;
            var tagsIdsList = myStatus.categoryIdToSelectedTags.get(category.id);
            if (isNotNull(tagsIdsList) && tagsIdsList.size() > 0){
                var tag = tagIdToTag.get(tagsIdsList[0]);
                filterHtml += "<td>" + filterElementHtml.replace(/filterElementBodyPlaceholder/, tag.name).replace(/categoryIdPlaceholder/g, category.id).replace(/tagIdPlaceholder/g, tag.id) + "</td>";
                filterHtml += "<td> + </td>";
                filterEmpty = false;
            }
        });
    }
    if (!filterEmpty && isEmpty(myStatus.searchPhrase)){
        filterHtml = filterHtml.substring(0, filterHtml.length-"<td> + </td>".length);
    }
    if (isNotEmpty(myStatus.searchPhrase)){
        filterHtml += "<td>" + filterSearchElementHtml.replace(/filterElementBodyPlaceholder/, myStatus.searchPhrase) + "</td>";
    }
    filterHtml += "</tr></table>";
    $('filterToolbar').innerHTML = filterHtml;
}

function paintAllTags(){
    if (!completedInitTags){
        setTimeout(paintAllTags, 200);
        return;
    }
    // standard categories
    categoryIdToTags.each(function(pair) {
        var category = categoryIdToCategory.get(pair.key);
        var categoryTags = pair.value;
        if (!category.approved || (category.mode != "all" && category.mode != menuItemSelected )){
            return;
        }
        paintCategory(category);
    });
    repaintTagsSelection();
    $('tagsContainer').style.visibility = "visible";
}

function paintCategory(category){
    var countOrder = category.editable ? true : false;
    var sizeLimit = category.editable ? 5 : null;
    $('category' + category.divId).innerHTML = getCategoryHtml(category, countOrder, sizeLimit);
}

function getTagColor(tag, selected){
    if (tag.categoryId == 1 && !isLinksMode()){
        return "#" + eval("domainColor" + tag.id);
    } else {
        return isNotNull(selected) && selected ? "#666666" : "";
    }
}

function getCategoryHtml(category, countOrder, sizeLimit){
    var categoryHtml = "";
    categoryHtml += categoryPaneHtml.replace(/categoryNamePlaceHolder/, category.name).replace(/categoryIdPlaceHolder/g, category.id);
    var tagsHtml = "";
    if (countOrder){
        var tagsCountList = categoryIdToTagsCountList[category.id];
        var selectedTag = null;
        if (myStatus.categoryIdToSelectedTags.size() > 0 && isNotNull(myStatus.categoryIdToSelectedTags.get(category.id)) && isNotNull(myStatus.categoryIdToSelectedTags.get(category.id)[0])){
            selectedTag = tagIdToTag.get(myStatus.categoryIdToSelectedTags.get(category.id)[0]);
        }
        var alreadyPaintedSelectedTag = false;
        for (var i=0; i<tagsCountList.size(); i++){
            // if last row
            if (isNotNull(sizeLimit) && i>=sizeLimit){
                tagsHtml += "<span onclick='openMoreTags(" + category.id + ")' class='link'>" + hMessages.getMessage('i18n.161') + "</span>";
                break;
            }
            // if one before last row
            if (isNotNull(sizeLimit) && i>=(sizeLimit-1) && !alreadyPaintedSelectedTag && isNotNull(selectedTag)){
                tagsHtml += getTagHtml(category, selectedTag);
                continue;
            }
            // if regular row
            tagsHtml += getTagHtml(category, tagIdToTag.get(tagsCountList[i].tagId));
            if (isNotNull(selectedTag) && selectedTag.id == tagsCountList[i].tagId){
                alreadyPaintedSelectedTag = true;
            }
        }
    } else {
        var categoryTags =categoryIdToTags.get(category.id);
        for (var i=0; i<categoryTags.size(); i++){
            tagsHtml += getTagHtml(category, categoryTags[i]);
        }
    }
    return categoryHtml.replace(/categoryPaneBodyPlaceHolder/, tagsHtml);
}

function getTagHtml(category, tag){
    var result = tagHtml.replace(/categoryIdPlaceholder/g, category.id).replace(/tagIdPlaceholder/g, tag.id).replace(/tagNamePlaceholder/g, tag.name);
    if (isEmpty(myStatus.searchPhrase)){
        result = result.replace(/tagItemsCount/, "(" + tagIdToTagCount.get(tag.id) + ")");
    } else {
        result = result.replace(/tagItemsCount/, "");
    }
    return result;
}

function addTagsCountData(){
    for (var i=0; i<categories.size(); i++){
        var tagsCountList = categoryIdToTagsCountList[categories[i].id];
        if (isNotNull(tagsCountList)){
            for (var j=0; j<tagsCountList.size(); j++){
                tagIdToTagCount.set(tagsCountList[j].tagId, tagsCountList[j].count);
            }
        }
    }
}

function openMoreTags(categoryId){
    var category = categoryIdToCategory.get(categoryId);
    var dialogContent = categoryPaneHtml.replace(/categoryNamePlaceHolder/, category.name).replace(/categoryIdPlaceHolder/g, category.id);
    var tagsHtml = "";
    var tagsCountList = categoryIdToTagsCountList[category.id];
    for (var i=0; i<tagsCountList.size(); i++){
        var tag = tagIdToTag.get(tagsCountList[i].tagId);
        tagsHtml += additionalTagHtml.replace(/categoryIdPlaceholder/g, category.id).replace(/tagIdPlaceholder/g, tag.id).replace(/tagNamePlaceholder/g, tag.name).replace(/tagItemsCount/, "(" + tagIdToTagCount.get(tag.id) + ")");
    }

    dialogContent = dialogContent.replace(/categoryPaneBodyPlaceHolder/, tagsHtml);
    generalDialog.setBody({text: dialogContent, height:300, isClosable:true});
    generalDialog.show();
}

function onDialogSelectTag(categoryId, tagId){
    generalDialog.hide();
    onSelectTag(categoryId, tagId);
}

///////////////////////
// Items
///////////////////////

function loadItems(){
    ajaxRequest("loadItems", null, renderingItems);
}

function reloadItems(){
    ajaxRequest("loadItems", "status=" + myStatus.toJSON(), renderingItems);
}

function renderingItems(res){
    var result = eval("(" + res.responseText + ")");
    itemsTotalCount = result.itemsTotalCount;
    items = result.items;
    categoryIdToTagsCountList = result.categoryIdToTagsCountList;
    addTagsCountData();
    paintAllTags();
    for (var i=0; i<items.size(); i++){
        itemIdToItem.set(items[i].id, items[i]);
    }

    if (isLinksMode()){
        // toolbar
        $('itemsDiv').innerHTML = getItemsToolbarHtml();

        // items
        if (itemsTotalCount > 0){
            for (i=0; i<items.size(); i++){
                paintItem(items[i]);
            }
        } else {
            $('itemsDiv').innerHTML += $('noItemsFoundDiv').innerHTML;
        }

        $('itemsDiv').innerHTML += getPagingHtml();
    } else {
        paintCalendar();
    }

    //
    if (isItemDialogOpened){
        generalDialog.repaint();
    }
}

function getItemsToolbarHtml(){
    return itemsToolbarHtml.replace(/timeRangePlaceholder/, myStatus.dateToString()).replace(/sortingMethodPlaceholder/, myStatus.sortingMethodToString()).replace(/pagingPlaceholder/, getPagingHtml());
}

function getPagingHtml(){
    var result = "";
    if (itemsTotalCount > 10){
        if (myStatus.pageNum > 1){
            result += "<span class='pagingActive' onclick='onPageNum(" + (myStatus.pageNum-1) + ");'>&#60;</span> ";
        } else {
            result += "<span class='pagingPassive'>&#60;</span> ";
        }
        var pageCount = 1 + itemsTotalCount/10;
        var printed3Dots = false;
        for (var i=1; i<=pageCount; i++){
            // print ...
            if ((pageCount > 13) &&
                ((i>2 && i<(myStatus.pageNum-2)) ||
                 (i<(pageCount-1) && i>(myStatus.pageNum+2)))){
                if (!printed3Dots){
                    result += "...  ";
                    printed3Dots = true;
                }
            }
            // or print a page number
            else {
                printed3Dots = false;
                // paint the number itself
                if (myStatus.pageNum != i){
                    result += "<span class='pagingActive' style='' onclick='onPageNum(" + i + ");'>" + i + "</span>&nbsp;&nbsp;";
                } else {
                    result += "<span style='font-weight:bold;' class='pagingPassive'>" + i + "</span>&nbsp;&nbsp;";
                }
            }
        }
        if (myStatus.pageNum < (1+(itemsTotalCount-itemsTotalCount%10)/10)){
            result += "<span class='pagingActive' onclick='onPageNum(" + (myStatus.pageNum+1) + ");'>&#62;</span> ";
        } else {
            result += "<span class='pagingPassive'>&#62;</span> ";
        }
    }
    return result;
}

function onPageNum(pageNum){
    myStatus.pageNum = pageNum;
    reloadItems();
    window.scrollTo(0, 0);
}

function paintItem(item){
    $('itemsDiv').innerHTML += getItemHtml(item) + "<div style='height:15px;'>&nbsp;</div>";
}

function getItemHtml(item){
    var itemHtml = itemPaneHtml.replace(/image_placeholder/, item.image).replace(/title_placeholder/, item.title).replace(/description_placeholder/, item.description).replace(/time_placeholder/, item.formattedTime).replace(/recommendation_placeholder/, "+"+item.recommendations).replace(/_MYID/g, item.id);
    if (isEmpty(item.link) || item.link == "http://"){
        itemHtml = itemHtml.replace(/link_placeholder/g, "");
    } else {
        itemHtml = itemHtml.replace(/link_placeholder/g, "href='" + item.link + "'");
    }

    if (item.type == 'event'){
        itemHtml = itemHtml.replace(/<!-- eventDetails_placeholder -->/, "<tr><td><b>" + hMessages.getMessage('i18n.162') + ": </b>" + item.formattedFromTo + "<br><b>" + hMessages.getMessage('i18n.164') + ": </b>" + item.location +  "</td></tr>")
    }

    // item left menu
    if (isNull(user) || (user.role != "admin" && user.id != item.creatorId)){
        itemHtml = itemHtml.replace("id=\"editButtonTr" + item.id + "\"", "id='editButtonTr" + item.id + "' style='display:none'");
        itemHtml = itemHtml.replace("id=editButtonTr" + item.id, "id='editButtonTr" + item.id + "' style='display:none'");
    }
    
    if (isNull(user) || user.role != "admin"){
        itemHtml = itemHtml.replace("id=\"approveButtonTr" + item.id + "\"", "id='approveButtonTr" + item.id + "' style='display:none'");
        itemHtml = itemHtml.replace("id=approveButtonTr" + item.id, "id='approveButtonTr" + item.id + "' style='display:none'");
        itemHtml = itemHtml.replace("id=\"recommendButtonTr" + item.id + "\"", "id='recommendButtonTr" + item.id + "' style='display:none'");
        itemHtml = itemHtml.replace("id=recommendButtonTr" + item.id, "id='recommendButtonTr" + item.id + "' style='display:none'");
    }

    // additional links (facebook, wikipedia)
    var additionalLinksHtml = "";
    if (item.type == "content"){
        if (isNotEmpty(item.facebook) || isNotEmpty(item.wikipedia)){
            additionalLinksHtml += "<table cellpadding='0' cellspacing='0' style='padding-top:1px; padding-bottom: 5px'><tr valign='top'><td style='color:#888888; white-space:nowrap; padding-left:2px'>[" + hMessages.getMessage('i18n.112') + ": </td><td style='padding-top:2px;'>";
            if (isNotEmpty(item.facebook)){
                additionalLinksHtml += "<a href='" + item.facebook + "' target='facebook" + item.id + "'><img style='padding-left:2px' src='images/facebookFavicon.bmp' alt=''></a>";
            }
            if (isNotEmpty(item.wikipedia)){
                additionalLinksHtml += "<a href='" + item.wikipedia + "' target='wikipedia" + item.id + "'><img style='padding-left:2px' src='images/wikipediaFavicon.bmp' alt=''></a>";
            }
            additionalLinksHtml += "</td><td style='color:#888888'>]</td></tr></table>";
        }
    } else {
        additionalLinksHtml += "<table><tr>";
        additionalLinksHtml += "<td>" + getGoogleEventButtonHtml(item) + "</td>";
        if (isNotEmpty(item.facebook)){
            additionalLinksHtml += "<td><a href='" + item.facebook + "' target='facebook" + item.id + "'><img style='padding-left:2px' src='images/facebookFavicon.bmp' title='" + hMessages.getMessage('i18n.113') + "' alt=''></a></td>";
        }
        additionalLinksHtml += "</tr></table>";
    }
    itemHtml = itemHtml.replace(/additionalLinks_placeholder/, additionalLinksHtml);

    // item tags
    var itemTagsHtml = "";
    categoryIdToCategory.each(function(pair){
        var category = pair.value;
        if (isNotNull(item.categoryIdToSelectedTags) && isNotNull(item.categoryIdToSelectedTags[category.id])){
            var itemTags = item.categoryIdToSelectedTags[category.id];
            for (var i=0; i<itemTags.size(); i++){
                var tag = tagIdToTag.get(itemTags[i]);
                itemTagsHtml += itemTagElementHtml.replace(/filterElementBodyPlaceholder/, tag.name).replace(/categoryIdPlaceholder/g, category.id).replace(/tagIdPlaceholder/g, tag.id);
            }
        }
    });
    itemHtml = itemHtml.replace(/tags_placeholder/, itemTagsHtml);

    // mark unapproved items
    var itemBorderStyle = "";
    if (item.approved == false) {
        itemBorderStyle = "border: 1px dashed #CFCFC4;";
    } else {
        itemBorderStyle = "border: 1px solid #CFCFC4;";
    }
    if (item.type == "event" && !isItemDialogOpened){
        itemBorderStyle += "border-top-width:0";
    }
    itemHtml = itemHtml.replace(/color: aliceblue/i, itemBorderStyle);

    return itemHtml;
}

function sortItems(sortingMethod){
    myStatus.sortingMethod = sortingMethod;
    myStatus.pageNum = 1;
    $('sortingMethodLink').innerHTML = myStatus.sortingMethodToString();
    reloadItems();
}

function openMoreActionsDialog(itemId){
    var editLabel = hMessages.getMessage('i18n.134');
    var deleteLabel = hMessages.getMessage('i18n.135');
    var copyLabel = hMessages.getMessage('i18n.136');
    var approveLabel = hMessages.getMessage('i18n.137');
    moreActionsRelevantItemId = itemId;
    moreActionsDialog.setBody({text: "<b>" + hMessages.getMessage('i18n.133') + "</b>", isClosable:true});
    if (user.role == "admin"){
        var item = itemIdToItem.get(itemId);
        if (item.approved){
            if (isLinksMode()){
                moreActionsDialog.setButtons({caption:editLabel, onclick: onEditItem}, {caption:deleteLabel, onclick: onRejectItem});
            } else {
                moreActionsDialog.setButtons({caption:editLabel, onclick: onEditItem}, {caption:copyLabel, onclick: onCopyItem}, {caption:deleteLabel, onclick: onRejectItem});
            }
        } else {
            if (isLinksMode()){
                moreActionsDialog.setButtons({caption:editLabel, onclick: onEditItem}, {caption:approveLabel, onclick: onApproveItem}, {caption:deleteLabel, onclick: onRejectItem});
            } else {
                moreActionsDialog.setButtons({caption:editLabel, onclick: onEditItem}, {caption:approveLabel, onclick: onApproveItem}, {caption:copyLabel, onclick: onCopyItem}, {caption:deleteLabel, onclick: onRejectItem});
            }
        }

    } else {
        if (isLinksMode()){
            moreActionsDialog.setButtons({caption:editLabel, onclick: onEditItem}, {caption:deleteLabel, onclick: onRejectItem});
        } else {
            moreActionsDialog.setButtons({caption:editLabel, onclick: onEditItem}, {caption:copyLabel, onclick: onCopyItem}, {caption:deleteLabel, onclick: onRejectItem});
        }
    }
    moreActionsDialog.show();
}

function onEditItem(){
    moreActionsDialog.hide();
    closeItemDialog();
    editItem(moreActionsRelevantItemId);
}

function approveItem(itemId){
    closeItemDialog();
    var url = 'moreActions';
    var params = 'action=approve&itemId=' + itemId;
    ajaxRequest(url, params, onCompleteApproveItem);
}

function rejectItem(itemId){
    closeItemDialog();
    var url = 'moreActions';
    var params = 'action=reject&itemId=' + itemId;
    ajaxRequest(url, params, onCompleteApproveItem);
}

function recommendItem(itemId){
	closeItemDialog();
    var url = 'moreActions';
    var params = 'action=recommend&itemId=' + itemId;
    ajaxRequest(url, params, onCompleteAllLangsItem);
}

function copyItem(itemId){
    closeItemDialog();
    var item = itemIdToItem.get(itemId);
    openShareDialog(item.type);
    newItem = new Item(item);
    newItem.id = null;
    newItem.recommendations = 0;
    newItem.exportData();
}

function onCompleteApproveItem(res){
    moreActionsRelevantItemId = null;
    reloadItems();
    moreActionsDialog.hide();
}

function onCompleteAllLangsItem(res){
    moreActionsRelevantItemId = null;
    reloadItems();
    moreActionsDialog.hide();
}

function editItem(itemId){
    openEditItem(itemId);
}

function shareInFacebook(itemId){
    var item = null;
    if (isItemDialogOpened){
        item = itemInDialog;
    } else {
        item = itemIdToItem.get(itemId);
    }
    var u = "http://www.humanisty.com/" + "?itemId=" + itemId;;
    var t = item.title;
    window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');
    return false;
}

function copyLink(itemId){
    generalDialog.setBody("<input id='copyLinkField' style='width:100%; direction:ltr' value='" + myDomain + "?itemId=" + itemId + "'>");
    generalDialog.setButtons({caption:hMessages.getMessage('i18n.157'), onclick: generalDialog.hide});
    generalDialog.show();
    autoSelectTextField($('copyLinkField'));
}

/*function recommendItem(itemId){
    if (isNull(user)){
        openLoginDialog();
    } else {
        var url = 'recommendItem';
        var params = 'itemId=' + itemId;
        ajaxRequest(url, params, onCompleteRecommendation);
    }
}*/

function onCompleteRecommendation(res){
    reloadItems();
}

function searchItems(){
    myStatus.searchPhrase = $('searchField').value;
    myStatus.pageNum = 1;
    repaintFilterToolbar();
    reloadItems();
}

///////////////////////
// Dates
///////////////////////

// simple date filterring
function setItemsDateRange(dateRange){
    myStatus.dateRangeType = "simple";
    myStatus.dateRange = dateRange;
    updateDates();
}

// advanced date filterring
function openDatesDialog(){
    datesDialog.setBody({text: dateDialogHtml, width:300, isClosable:true});
    datesDialog.setButtons({caption:hMessages.getMessage('i18n.105'), onclick: updateDates}, {caption:hMessages.getMessage('i18n.106'), onclick: datesDialog.hide});
    datesDialog.show();
}

function updateDates(){
    var url = 'loadItems';
    if (myStatus.dateRangeType == "advanced"){
        myStatus.fromDateType = getSelectedRadioElement(document.getElementsByName('fromDateType')).value;
        myStatus.fromYear = document.getElementsByName('fromYear')[0].value;
        myStatus.fromMonth = document.getElementsByName('fromMonth')[0].value;
        myStatus.fromDay = document.getElementsByName('fromDay')[0].value;
        myStatus.toDateType = getSelectedRadioElement(document.getElementsByName('toDateType')).value;
        myStatus.toYear = document.getElementsByName('toYear')[0].value;
        myStatus.toMonth = document.getElementsByName('toMonth')[0].value;
        myStatus.toDay = document.getElementsByName('toDay')[0].value;
    }
    myStatus.pageNum = 1;
    var params = "status=" + myStatus.toJSON();
    $('dateFilterLink').innerHTML = myStatus.dateToString();
    ajaxRequest(url, params, onCompleteUpdateDates);
}

function onCompleteUpdateDates(res){
    renderingItems(res);
    datesDialog.hide();
}

///////////////////
// dates popup menu
///////////////////


var datesMenuOpenTime = 0;
var sortingMenuOpenTime = 0;

function onoverMenuItem(menuItem){
    menuItem.style.backgroundColor = "#dbe6f4";
}

function onoutMenuItem(menuItem){
    menuItem.style.backgroundColor = "";
}

function showDatesMenu(){
    datesMenuOpenTime = new Date().getTime();
    $('dateFilterMenu').show();
}

function hideDatesMenu(){
    if (isNotNull($('dateFilterMenu'))){
        $('dateFilterMenu').hide();
    }
}

function showSortingMenu(){
    sortingMenuOpenTime = new Date().getTime();
    $('sortingMenu').show();
}

function hideSortingMenu(){
    if (isNotNull($('sortingMenu'))){
        $('sortingMenu').hide();
    }
}


function onBodyClick(){
    if (datesMenuOpenTime + 200 < new Date().getTime()){
        hideDatesMenu();
    }
    if (sortingMenuOpenTime + 200 < new Date().getTime()){
        hideSortingMenu();
    }
}

///////////////////////
// Unsubscribe
///////////////////////

function openUnsubscribeDialog(unsubscribeEmail){
    unsubscribeDialog.setBody({text: unsubscribeHtml, width:350, isClosable:true});
    unsubscribeDialog.setButtons({caption:hMessages.getMessage('i18n.137'), onclick: sendUnsubscribe}, {caption:hMessages.getMessage('i18n.106'), onclick: unsubscribeDialog.hide});
    $('unsubscribeEmail').innerHTML = unsubscribeEmail;
    unsubscribeDialog.show();
}

function sendUnsubscribe(){
    ajaxRequest("unsubscribe", "email=" + $('unsubscribeEmail').innerHTML, onUnsubscribeComplete);
}

function onUnsubscribeComplete(){
    unsubscribeDialog.hide();
    generalDialog.setBody({text: hMessages.getMessage('i18n.200')});
    generalDialog.setButtons({caption:hMessages.getMessage('i18n.157'), onclick: generalDialog.hide});
    generalDialog.show();
}

///////////////////////
// Login Dialog
///////////////////////

function openLoginDialog(){
    identificationDialog.setBody({text: identificationHtml, width:300, isClosable:true});
    $('loginDiv').show();
    $('registrationDiv').hide();
    identificationDialog.show();
}

function openRegistrationDialog(){
    authorizedFunction = null;
    identificationDialog.setBody({text: identificationHtml, width:300, isClosable:true});
    $('registrationDiv').show();
    $('loginDiv').hide();
    identificationDialog.show();
    if (isNotEmpty($('email').value)){
        $('registrationEmail').value = $('email').value;
        $('registrationTitle').innerHTML = hMessages.getMessage('i18n.138');
        $('registrationButton').innerHTML = hMessages.getMessage('i18n.139');
    }
}

function submitLogin(){
    $('loginButton').disabled = "disabled";
    $('loginButton').className = "disabled";
    var url = 'login';
    var params = 'email=' + document.getElementsByName('loginEmail')[0].value + '&password=' + document.getElementsByName('loginPassword')[0].value + '&rememberMe=' + document.getElementsByName('rememberMe')[0].checked;
    ajaxRequest(url, params, onCompleteLogin);
}

function onCompleteLogin(res){
    onCompleteIdentification(res, "login");
}

function submitRegistration(){
    $('registrationButton').disabled = "disabled";
    $('registrationButton').className = "disabled";
    var url = 'registration';
    var params = 'email=' + document.getElementsByName('registrationEmail')[0].value + '&password=' + document.getElementsByName('registrationPassword')[0].value + '&confirmPassword=' + document.getElementsByName('confirmPassword')[0].value;
    ajaxRequest(url, params, onCompleteRegistration);
}

function onCompleteRegistration(res){
    onCompleteIdentification(res, "registration");
}

function onCompleteIdentification(res, action){
    $(action + 'Button').disabled = "";
    $(action + 'Button').className = "";
    var response = res.responseText;
    if (response.startsWith("failure")){
        $(action + 'ErrorDiv').innerHTML = response.substring('failure'.length);
        $(action + 'ErrorDiv').show();
        identificationDialog.repaint();
    } else {
        user = eval("(" + response.substring('success'.length) + ")");
        identificationDialog.hide();
        if (isNotNull(authorizedFunction)){
            authorizedFunction();
            authorizedFunction = null;
        }
        renderUserPane();
        reloadItems();
    }
}

function logout(){
    var url = 'logout';
    ajaxRequest(url, null, onCompleteLogout);
}

function onCompleteLogout(){
    user = null;
    myStatus.pageNum = 1;
    renderUserPane();
    reloadItems();
}

function openForgotPasswordDialog(){
    forgotPasswordDialog.setBody({text: forgotPasswordHtml, width:350, isClosable:true});
    forgotPasswordDialog.setButtons({caption:hMessages.getMessage('i18n.105'), onclick: sendForgotPassword}, {caption:hMessages.getMessage('i18n.106'), onclick: forgotPasswordDialog.hide});
    forgotPasswordDialog.show();
}

function sendForgotPassword(){
    ajaxRequest("forgotPassword", "email=" + $('forgotPassword').value, onForgotPasswordComplete);
}

function onForgotPasswordComplete(){
    forgotPasswordDialog.hide();
}


///////////////////
// User & Profile
///////////////////

function renderUserPane(){
    if (isNotNull(user)){
        $('loginLink').hide();
        $('logoutLink').show();
    } else {
        $('loginLink').show();
        $('logoutLink').hide();
    }
    $('rightMenu').style.visibility = "visible";
}

function openProfileDialog(){
    if (isNull(user)){
        openLoginDialog();
        authorizedFunction = openProfileDialog;
    } else {
        profileDialog.setBody({text: profileDialogHtml, width:400, isClosable:true});
        profileDialog.setButtons({caption:hMessages.getMessage('i18n.159'), onclick: updateProfile}, {caption:hMessages.getMessage('i18n.106'), onclick: profileDialog.hide});
        $('mailFrequency_' + user.mailPolicy.frequency).checked = "checked";
        $('mailItemsType_links').checked = user.mailPolicy.links ? "checked" : "";
        $('mailItemsType_events').checked = user.mailPolicy.events ? "checked" : "";
        $('mailDomains_20').checked = user.mailPolicy.justice ? "checked" : "";
        $('mailDomains_22').checked = user.mailPolicy.peace ? "checked" : "";
        $('mailDomains_24').checked = user.mailPolicy.environment ? "checked" : "";
        $('mailDomains_25').checked = user.mailPolicy.animals ? "checked" : "";
        $('mailDomains_39').checked = user.mailPolicy.other ? "checked" : "";
        profileDialog.show();
    }
}

function updateProfile(){
    var url = 'updateProfile';
    var params = "jsonProfile={ frequency:'" + getSelectedRadioElement(document.getElementsByName('mailFrequency')).value +
                 "' , links:" + ($('mailItemsType_links').checked) +
                 " , events:" + ($('mailItemsType_events').checked) +
                 " , justice:" + ($('mailDomains_20').checked) +
                 " , peace:" + ($('mailDomains_22').checked) +
                 " , environment:" + ($('mailDomains_24').checked) +
                 " , animals:" + ($('mailDomains_25').checked) +
                 " , other:" + ($('mailDomains_39').checked) +
                 "}";
    ajaxRequest(url, params, onCompleteUpdateProfile);
}

function onCompleteUpdateProfile(res){
    user.mailPolicy = eval("(" + res.responseText + ")");
    profileDialog.hide();
}


///////////////////
// Status
///////////////////

function Status(jsonObj){

    var _this = this;
    _this.mode = null;
    _this.categoryIdToSelectedTags = null;
    _this.searchPhrase = null;
    _this.dateRangeType = null;
    _this.dateRange = null;
    _this.fromDateType = null;
    _this.fromYear = null;
    _this.fromMonth = null;
    _this.fromDay = null;
    _this.toDateType = null;
    _this.toYear = null;
    _this.toMonth = null;
    _this.toDay = null;
    _this.sortingMethod = null;
    _this.pageNum = null;
    _this.calendarDate = null;
    _this.calendarStartDate = null;
    _this.calendarEndDate = null;

    _this.fromJSON = function(jsonObj) {
        _this.mode = (isNotNull(jsonObj.mode) ? jsonObj.mode : 'events');
        _this.categoryIdToSelectedTags = (isNotNull(jsonObj.categoryIdToSelectedTags) ? jsonObj.categoryIdToSelectedTags : new Hash());
        _this.searchPhrase = (isNotNull(jsonObj.searchPhrase) ? jsonObj.searchPhrase : '');
        _this.dateRangeType = (isNotNull(jsonObj.dateRangeType) ? jsonObj.dateRangeType : null);
        _this.dateRange = (isNotNull(jsonObj.dateRange) ? jsonObj.dateRange : "all");
        _this.fromDateType = (isNotNull(jsonObj.fromDateType) ? jsonObj.fromDateType : null);
        _this.fromYear = (isNotNull(jsonObj.fromYear) ? jsonObj.fromYear : null);
        _this.fromMonth = (isNotNull(jsonObj.fromMonth) ? jsonObj.fromMonth : null);
        _this.fromDay = (isNotNull(jsonObj.fromDay) ? jsonObj.fromDay : null);
        _this.toDateType = (isNotNull(jsonObj.toDateType) ? jsonObj.toDateType : null);
        _this.toYear = (isNotNull(jsonObj.toYear) ? jsonObj.toYear : null);
        _this.toMonth = (isNotNull(jsonObj.toMonth) ? jsonObj.toMonth : null);
        _this.toDay = (isNotNull(jsonObj.toDay) ? jsonObj.toDay : null);
        _this.sortingMethod = (isNotNull(jsonObj.sortingMethod) ? jsonObj.sortingMethod : 'date');
        _this.pageNum = (isNotNull(jsonObj.pageNum) ? jsonObj.pageNum : 1);
        _this.calendarDate = (isNotNull(jsonObj.calendarDate) ? new Date(jsonObj.calendarDate) : new Date());
        _this.calendarStartDate = (isNotNull(jsonObj.calendarStartDate) ? jsonObj.calendarStartDate : null);
        _this.calendarEndDate = (isNotNull(jsonObj.calendarEndDate) ? jsonObj.calendarEndDate : null);
    };

    _this.toJSON = function() {
        var result = "{ mode:'" + _this.mode +
                     "', categoryIdToSelectedTags:" + (isNotNull(_this.categoryIdToSelectedTags) ? _this.categoryIdToSelectedTags.toJSON() : null) +
                     " , searchPhrase:'" + (sdEscape(_this.searchPhrase)) +
                     "' , dateRangeType:'" + (sdEscape(_this.dateRangeType)) +
                     "' , dateRange:'" + (sdEscape(_this.dateRange)) +
                     "' , fromDateType:'" + (sdEscape(_this.fromDateType)) +
                     "', fromYear:'" + (sdEscape(_this.fromYear)) +
                     "', fromMonth:'" + (sdEscape(_this.fromMonth)) +
                     "', fromDay:'" + (sdEscape(_this.fromDay)) +
                     "', toDateType:'" + _this.toDateType +
                     "', toYear:'" + (sdEscape(_this.toYear)) +
                     "', toMonth:'" + (sdEscape(_this.toMonth)) +
                     "', toDay:'" + (sdEscape(_this.toDay)) +
                     "', sortingMethod:'" + (sdEscape(_this.sortingMethod)) +
                     "', pageNum:" + (_this.pageNum) +
                     ", calendarDate:" + _this.calendarDate.getTime() +
                     ", calendarStartDate:" + _this.calendarStartDate +
                     ", calendarEndDate:" + _this.calendarEndDate +
                     "}";
        return result;
    };

    _this.dateToString = function(){
        var result = "";
        if (isNull(_this.dateRangeType) ||_this.dateRangeType == "simple"){
            if (isNull(_this.dateRange) || _this.dateRange == "all"){
                return hMessages.getMessage('i18n.69');
            } else if (_this.dateRange == "month"){
                return hMessages.getMessage('i18n.70');
            } else if (_this.dateRange == "week"){
                return hMessages.getMessage('i18n.71');
            }
        }
        if (_this.fromDateType == "theBeginning"){
            result += hMessages.getMessage('i18n.64');
        } else if (_this.fromDateType == "lastVisit"){
            result += hMessages.getMessage('i18n.65');
        } else {
            result += hMessages.getMessage('i18n.140') + _this.fromDay + "/" + _this.fromMonth + "/" + _this.fromYear;
        }
        if (_this.toDateType == "currentDate"){
            result += " " + hMessages.getMessage('i18n.141');
        } else {
            result += " " + hMessages.getMessage('i18n.142') + _this.toDay + "/" + _this.toMonth + "/" + _this.toYear;
        }
        return result;
    };

    _this.sortingMethodToString = function(){
        if (_this.sortingMethod == "date"){
            return hMessages.getMessage('i18n.68');
        } if (_this.sortingMethod == "rank"){
            return hMessages.getMessage('i18n.88');
        }
        return "";
    };

    _this.setSelectedTag = function(categoryId, tagId){
        _this.categoryIdToSelectedTags.set(categoryId, [tagId]);
    };

    _this.addSelectedTag = function(categoryId, tagId){
        var tags = _this.categoryIdToSelectedTags.get(categoryId);
        if (isNull(tags)){
            _this.categoryIdToSelectedTags.set(categoryId, new Array());
        }
        _this.categoryIdToSelectedTags.get(categoryId).push(tagId);
    };

    _this.clearCategorySelection = function(categoryId){
        _this.categoryIdToSelectedTags.unset(categoryId);
    };

    _this.clearTagSelection = function(categoryId, tagId){
        var tags = _this.categoryIdToSelectedTags.get(categoryId);
        for (var i=0; i<tags.size(); i++){
            if (tags[i] == tagId){
                _this.categoryIdToSelectedTags.set(categoryId, tags.without(tagId));
                if (_this.categoryIdToSelectedTags.get(categoryId).size() == 0){
                    _this.clearCategorySelection(categoryId);
                }
            }
        }
    };

    _this.isTagSelected = function(categoryId, tagId){
        var tags = _this.categoryIdToSelectedTags.get(categoryId);
        if (isNotNull(tags)){
            for (var i=0; i<tags.size(); i++){
                if (tags[i] == tagId){
                    return true;
                }
            }
        }
        return false;
    };

    _this.isFilterEmpty = function(){
        var isEmpty = true;
        if (isNotEmpty(_this.searchPhrase)){
            return false;
        }
        _this.categoryIdToSelectedTags.each(function(pair){
            if (isNotNull(pair.value) && pair.value.size() > 0){
                isEmpty = false;
            }
        });
        return isEmpty;
    };

    _this.clearFilter = function(){
        _this.searchPhrase = "";
        _this.categoryIdToSelectedTags = new Hash();
    };

    _this.fromJSON(jsonObj);
}


//////////////////
// Events
//////////////////
function setCalendarView(view){
    calendarView = view;
    updateStatusCalendarBoundaries();
    reloadItems();
    //paintCalendar();
}

function initCalendar(){
    calendarView = isEmbed ? "month" : "week";
    myStatus.calendarDate = new Date();
    updateStatusCalendarBoundaries();
}

function paintCalendar(){
    if (calendarView == "week"){
        paintCalendarWeek();
    } else {
        paintCalendarSkeleton();
        paintCalendarDates();
        paintCalendarEvents();
    }
}

function paintCalendarSkeleton(){
    var calendarHtml = "";
    var numOfDays = 7;
    var numOfWeeks = calendarNumOfWeeks;
    var numOfColumns = numOfDays+2;
    var numOfRows = numOfWeeks+2;

    var days = [hMessages.getMessage('i18n.143'), hMessages.getMessage('i18n.144'), hMessages.getMessage('i18n.145'), hMessages.getMessage('i18n.146'), hMessages.getMessage('i18n.147'), hMessages.getMessage('i18n.148'), hMessages.getMessage('i18n.149')];
    var cellNum = 0;
    calendarHtml += "<table style='table-layout:fixed' class='wmax' cellpadding='0' cellspacing='0'>";
    for (var y=0; y<numOfRows; y++){
        calendarHtml += "<tr>";
        for (var x=0; x<numOfColumns; x++){
            // if calendar frame
            if (x==0 || x==(numOfColumns-1) || y==0 || y==(numOfRows-1)){
                // if column header
                if (y==0 && x>0 && x<(numOfColumns-1)){
                    calendarHtml += "<td class='columnHeader'>" + days[x-1] + "</td>";
                } else {
                    calendarHtml += "<td class='calendarFrame'></td>";
                }
            }
            // if calendar cell
            else {
                cellNum++;
                var style = "";
                if (x<(numOfColumns-1)){
                    style += "border-left:1px solid #C3D9FF;";
                }
                if (y<(numOfRows-1)){
                    style += "border-bottom:1px solid #C3D9FF;";
                }
                calendarHtml += "<td id='calendarCell" + cellNum + "' class='calendarCell' style='" + style + "'>" + calendarCellHtml.replace(/_cellNumPlaceholder/g, cellNum) + "</td>";
            }
        }
        calendarHtml += "</tr>";
    }
    calendarHtml += "</table>";
    $('calendarDiv').innerHTML = getCalendarToolbarHtml() + calendarHtml;
    updateCalendarToolbar();
}

function paintCalendarDates(){
    var date = new Date(myStatus.calendarDate.getFullYear(), myStatus.calendarDate.getMonth(), 1);
    var now = new Date();
    while (date.getDay() != 0){
        date.setDate(date.getDate()-1);
    }
    for (var i=1; i<=calendarNumOfWeeks*7; i++){
        if (date.getDate() != 1){
            $('calendarCellHeader' + i).innerHTML = date.getDate();
        } else {
            $('calendarCellHeader' + i).innerHTML = date.getDate() + " " + hMessages.getMessage('i18n.160') + monthsNames[date.getMonth()];
        }
        if (date.getMonth() != myStatus.calendarDate.getMonth()){
            $('calendarCellHeader' + i).className = "cellHeader cellHeaderOtherMonth";
        }
        if (date.getDate() == myStatus.calendarDate.getDate() && date.getMonth() == now.getMonth()){
            $('calendarCellHeader' + i).className = "cellHeader cellHeaderToday";
            $('calendarCellBody' + i).className = "cellBody cellBodyToday";
        }
        date.setDate(date.getDate()+1);
    }
}

function paintCalendarEvents(){
    if (isNotNull(items)){
        for (var i=0; i<items.size(); i++){
            var item = itemIdToItem.get(items[i].id);
            var itemColor = "";
            if (isNotNull(item.domainIds) && item.domainIds.size() > 0){
                itemColor = getTagColor(tagIdToTag.get(item.domainIds[0]));
            }
            $('calendarCellBody' + dayInMonthToCellNumber(item.fromDay, item.fromMonth, item.fromYear)).innerHTML += "<div class='link calendarEventInCell' style='color:" + itemColor + ";' onclick='openEventInDialog(" + item.id + ")'><span style='font-size:10px'>" + item.fromHour + ":" + item.fromMinutes + " </span>" + item.title + "</div>";
        }
    }
}

function dayInMonthToCellNumber(dayInMonth, month, year){
    var result = null;
    var presentedMonth = myStatus.calendarDate.getMonth();
    var presentedYear = myStatus.calendarDate.getFullYear();
    var relativeMonth = ( ((Number(month)+1)+Number(year)*12) - ((Number(presentedMonth)+1)+Number(presentedYear)*12) ); // -1: previous month, 0: current month, 1: next month
    if (relativeMonth == -1){
        var date = new Date(year, month,  dayInMonth);
        result = Number(date.getDay()) + 1;
    } else if (relativeMonth == 0){
        result = Number(getFirstDayOfMonth(presentedMonth, presentedYear)) + Number(dayInMonth);
    } else {
        result = Number(getFirstDayOfMonth(presentedMonth, presentedYear)) + Number(getDaysInMonth(presentedMonth, presentedYear)) + Number(dayInMonth);
    }
    return result;
}

function getDaysInMonth(month, year)
{
    return new Date(year, month+1, 0).getDate();
}

function getFirstDayOfMonth(month, year){
    return new Date(year, month, 1).getDay();
}

function getNumOfRows(month, year){
    var result = null;
    var firstDayOfMonth = (getFirstDayOfMonth(month, year)) % 7;
    var firstDayOfNextMonth = (7 - (getFirstDayOfMonth(month+1, year))) % 7;
    result = Math.round((firstDayOfMonth + getDaysInMonth(month, year) + firstDayOfNextMonth) / 7 - 0.5);
    return result;
}

function goNextMonth(){
    if (calendarView == "month"){
        myStatus.calendarDate.setMonth(myStatus.calendarDate.getMonth()+1);
    } else {
        myStatus.calendarDate.setDate(myStatus.calendarDate.getDate()+7);
    }
    updateStatusCalendarBoundaries();
    reloadItems();
}

function goPrevMonth(){
    if (calendarView == "month"){
        myStatus.calendarDate.setMonth(myStatus.calendarDate.getMonth()-1);
    } else {
        myStatus.calendarDate.setDate(myStatus.calendarDate.getDate()-7);
    }
    updateStatusCalendarBoundaries();
    reloadItems();
}

function goThisMonth(){
    myStatus.calendarDate = new Date();
    updateStatusCalendarBoundaries();
    reloadItems();
}

function updateThisMonthButton(){
    var now = new Date();
    var isToday = null;
    if (calendarView == "month"){
        isToday = myStatus.calendarDate.getMonth() == now.getMonth() && myStatus.calendarDate.getFullYear() == now.getFullYear();
    } else {
        isToday = myStatus.calendarDate.getDate() == now.getDate() && myStatus.calendarDate.getMonth() == now.getMonth() && myStatus.calendarDate.getFullYear() == now.getFullYear();
    }
    $('thisMonthButton').className = isToday ? "disabled" : "";
}

function updateCalendarLabel(){
    if (calendarView == "month"){
        $('calendarLabel').innerHTML = monthsNames[myStatus.calendarDate.getMonth()] + " " + myStatus.calendarDate.getFullYear();
    } else {
        var toDate = new Date(myStatus.calendarDate.getTime());
        toDate.setDate(toDate.getDate()+7);
        $('calendarLabel').innerHTML = myStatus.calendarDate.getDate() + " " + hMessages.getMessage('i18n.160') + monthsNames[myStatus.calendarDate.getMonth()] + " - " + toDate.getDate() + " " + hMessages.getMessage('i18n.160') + monthsNames[toDate.getMonth()];
    }
}

function updateStatusCalendarBoundaries(){
    calendarNumOfWeeks = getNumOfRows(myStatus.calendarDate.getMonth(), myStatus.calendarDate.getFullYear());
    var calendarBoundaries = getCalendarDateBoundaries();
    myStatus.calendarStartDate = calendarBoundaries.start;
    myStatus.calendarEndDate = calendarBoundaries.end;
}

function openEventInDialog(itemId){
    var item = itemIdToItem.get(itemId);
    openItemDialog(item, eventPrevNextHeaderHtml);
    var currentItemIndex = getItemIndex(item);
    $('nextOpenedEventArrow').style.visibility = currentItemIndex < (items.size()-1) ? 'visible' : 'hidden';
    $('prevOpenedEventArrow').style.visibility = currentItemIndex > 0 ? 'visible' : 'hidden';
}

function browseEvent(nextOrPrev){
    var currentItemIndex = getItemIndex(itemInDialog);
    openEventInDialog(nextOrPrev == "next" ? items[currentItemIndex+1].id : items[currentItemIndex-1].id);
}

function getItemIndex(item){
    for (var i=0; i<items.size(); i++){
        if (item.id == items[i].id){
            currentItemIndex = i;
        }
    }
    return currentItemIndex;
}

function getCalendarDateBoundaries(){
    var result = {start: null, end: null};
    if (calendarView == "month"){
        var date = new Date(myStatus.calendarDate.getFullYear(), myStatus.calendarDate.getMonth(), 1);
        while (date.getDay() != 0){
            date.setDate(date.getDate()-1);
        }
        result.start = date.getTime();
        date.setDate(date.getDate()+calendarNumOfWeeks*7);
        result.end = date.getTime();
    } else {
        var date = new Date(myStatus.calendarDate.getTime());
        result.start = date.getTime();
        date.setDate(date.getDate()+7);
        result.end = date.getTime();
    }
    return result;
}

function getGoogleEventButtonHtml(item){
    var result = "<a href='http://www.google.com/calendar/event?action=TEMPLATE&text=" + encodeURIComponent(item.title) + "&dates=" + item.fromYear + (item.fromMonth.length == 1 ? ("0" + (Number(item.fromMonth) + 1)) : (Number(item.fromMonth) + 1)) + (item.fromDay.length == 1 ? "0" + item.fromDay : item.fromDay) + "T" +  (item.fromHour.length == 1 ? "0" + item.fromHour : item.fromHour) + (item.fromMinutes.length == 1 ? "0" + item.fromMinutes : item.fromMinutes) + "00/" + item.toYear + (item.toMonth.length == 1 ? ("0" + (Number(item.toMonth) + 1)) : (Number(item.toMonth) + 1)) + (item.toDay.length == 1 ? "0" + item.toDay : item.toDay) + "T" +  (item.toHour.length == 1 ? "0" + item.toHour : item.toHour) + (item.toMinutes.length == 1 ? "0" + item.toMinutes : item.toMinutes) + "00" + "" + /*item.description +*/ "&location=" + encodeURIComponent(item.location) + "&details=" + encodeURIComponent(hMessages.getMessage('i18n.150') + ((isNotNull(item.link) && item.link.length > 10) ? item.link : myDomain + "?itemId=" + item.id)) + "&trp=false&sprop=&sprop=name:' target='_blank'><img src='images/googleCalendar.bmp' title='" + hMessages.getMessage('i18n.151') + "'></a>";
    return result;
}

function paintCalendarWeek(){
    var weekHtml = "";
    if (items.length == 0){
        $('calendarDiv').innerHTML = getCalendarToolbarHtml() + "<p align='center'>" + hMessages.getMessage('i18n.152') + "</p>";
    } else {
        var dayInWeek = new Date(items[0].fromDateTime).getDay();
        var dayEventsHtml = "";
        for (var i=0; i<items.length; i++){
            dayEventsHtml += getItemHtml(items[i]);
            var nextEventDay = null;
            if (i+1 < items.length){
                nextEventDay = new Date(items[i+1].fromDateTime).getDay();
            }
            if (nextEventDay == null || nextEventDay != dayInWeek){
                weekHtml += calendarDayHeaderHtml.replace(/formattedDay_placholder/, getDayEventsTitle(new Date(items[i].fromDateTime))).replace(/dayEvents_placeholder/, dayEventsHtml) + "<br><br>";
                dayInWeek = nextEventDay;
                dayEventsHtml = "";
            }
        }
        $('calendarDiv').innerHTML = getCalendarToolbarHtml() + "<div style='height:5px'> </div>" + weekHtml;
    }
    updateCalendarToolbar();
}

function getCalendarToolbarHtml(){
    return calendarToolbarHtml.replace(/weekTabClass/, calendarView == "week" ? "selectedTab" : "unselectedTab").replace(/monthTabClass/, calendarView == "month" ? "selectedTab" : "unselectedTab")
}

function updateCalendarToolbar(){
    updateThisMonthButton();
    updateCalendarLabel();
    if (calendarView == "month"){
        $('weekTab').style.marginLeft = "-1px";
    } else {
        $('monthTab').style.marginRight = "-1px";
    }
    if (isEmbed){
        $('embededAddEventLink').show();
    }
}

function getDayEventsTitle(date){
    var result = "";
    var today = new Date();
    if (date.getDate() == today.getDate() && date.getMonth() == today.getMonth()){
        result += hMessages.getMessage('i18n.85') + ": ";
    } else if (date.getDate() == (today.getDate()+1) && date.getMonth() == today.getMonth()){
        result += hMessages.getMessage('i18n.165') + ": ";
    }
    result += weekDaysNames[date.getDay()] + ", " + date.getDate() + " " + hMessages.getMessage('i18n.160') + monthsNames[date.getMonth()];
    return result;
}

/////////////////
// Contact Us
/////////////////
var isContactUs = null;

function openContactUsDialog(){
    isContactUs = true;
    openContactUsOrRequiredDialog();
}

function openRequiredDialog(){
    isContactUs = false;
    openContactUsOrRequiredDialog();
}

function openContactUsOrRequiredDialog(){
    contactUsDialog.setBody({text: contactUsDialogHtml, width:320, isClosable:true});
    if (!isContactUs){
        $('contactUsTitle').innerHTML = hMessages.getMessage('i18n.59');
        $('contactUsContentLabel').innerHTML = hMessages.getMessage('i18n.163') + ":";
        $('volunteersDescription').style.display = "block";
    }
    contactUsDialog.setButtons({caption:hMessages.getMessage('i18n.105'), onclick: sendContactUs}, {caption:hMessages.getMessage('i18n.106'), onclick: contactUsDialog.hide});
    contactUsDialog.show();
}

function sendContactUs(){
    var url = 'contactUs';
    var params = "jsonString={type:'" + (isContactUs ? 'contactUs' : 'volunteers') + "', firstName:'" + sdEscape($('contactUs_firstName').value) + "', lastName:'" + sdEscape($('contactUs_lastName').value) + "', email:'" + sdEscape($('contactUs_email').value) + "', content:'" + sdEscape($('contactUs_content').value) + "'}";
    $('blockDiv').show();
    ajaxRequest(url, params, onCompleteContactUs);
}

function onCompleteContactUs(){
    $('blockDiv').hide();
    $('contactUsTitle').innerHTML = hMessages.getMessage('i18n.72');
    if (isContactUs){
        $('contactUsBody').innerHTML = hMessages.getMessage('i18n.153') + "<br>" + hMessages.getMessage('i18n.154');
    } else {
        $('contactUsBody').innerHTML = hMessages.getMessage('i18n.155') + "<br>" + hMessages.getMessage('i18n.156');
    }
    contactUsDialog.setButtons({caption:hMessages.getMessage('i18n.102'), onclick: contactUsDialog.hide});
    contactUsDialog.repaint();
}

///////////////////
// About Us
///////////////////

function openAboutUsDialog(){
    aboutUsDialog.setBody({text: aboutUsDialogHtml, width:380, isClosable:true});
    aboutUsDialog.setButtons({caption:hMessages.getMessage('i18n.157'), onclick: aboutUsDialog.hide});
    aboutUsDialog.show();
}

///////////////////
// Random Item
///////////////////
function getRandomItem(action){
    var url = 'getRandomItem';
    ajaxRequest(url, "action=" + action, onCompleteGetRandomItem);
}

function onCompleteGetRandomItem(res){
    var result = eval("(" + res.responseText + ")");
    itemInDialog = randomItem = result.item;
    openItemDialog(itemInDialog, openedRandomItemHeaderHtml);
    $('nextOpenedRandomItemArrow').style.visibility = result.hasNext ? 'visible' : 'hidden';
    $('prevOpenedRandomItemArrow').style.visibility = result.hasPrev ? 'visible' : 'hidden';
}


////////////////////////
// Recommended Item
////////////////////////
function openRecommendedItem(){
    openItemDialog(recommendedItem);
}

/////////////////
// Item Dialog
/////////////////
function openItemDialog(item, prefixHtml){
    isItemDialogOpened = true;
    itemInDialog = item;
    var itemHtml = "";
    if (isNotNull(prefixHtml)){
        itemHtml += prefixHtml;
    }
    itemHtml += getItemHtml(item);
    if (isEmbed){
        generalDialog.setBody({text: itemHtml, width:400});

    } else {
        generalDialog.setBody({text: itemHtml, width:630});
    }
    if (isEmbed){
        document.getElementById('itemSideToolbarTd' + itemInDialog.id).innerHTML = "";
    }
    Event.observe($('image' + itemInDialog.id), "load", repaintItemDialog);
    generalDialog.setButtons({caption: hMessages.getMessage('i18n.157'), onclick: closeItemDialog});
    generalDialog.show();
    if (isEmbed){
        $(generalDialog.dialogId).style.top = "100px";
    }
}

function repaintItemDialog(){
    generalDialog.repaint();
    if (isEmbed){
        $(generalDialog.dialogId).style.top = "100px";
    }
}

function closeItemDialog(){
    isItemDialogOpened = false;
    generalDialog.hide();
    itemInDialog = null;
}
