// preset alert names to be rendered in the balloon.
var presetAlertNames = {
    NewDomainInventory: 'NEWLY LISTED',
    //RecentSales: 'RECENTLY SOLD',
    NewsLetter: 'BUYDOMAINS NEWSLETTER',
    BusinessServices: 'BUSINESS SERVICES',
    PressRelease: 'PRESS RELEASES'
}

// registry of commands
// it contains all of the functions that implement behaviours that is different for different commands.
var commandRegistry = {
    onOffKeyword: {
        render: function (command) {
            return getTurnOnOffString(command) + ' keyword alert for <b>' + command.attributes['keyword'] + '</b>';
        },
        commandRecorded: function (command) {
            var selectedID = command.attributes['selectedID'];
            switchKeyword(selectedID, command.attributes['onOff']);
            command.attributes.keyword = findKeywordParameter(selectedID);
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID && existing.attributes.onOff ^ newCommand.attributes.onOff;
        },
        replace: nullifyExisting
    },
    addKeyword: {
        render: function (command) {
            return 'Create keyword alert for <b>' + command.attributes['parameter'] + '</b>';
        },
        validate: function(command, commands) {
            return command.attributes['parameter'].strip() != '';
        },
        commandRecorded: function (command) {
            var newId = generateId();
            command.attributes['newId'] = newId;
            command.attributes['frequency'] = 'Weekly'; // default for new keywords
            command.attributes['parameter'] = command.attributes['parameter'].strip();
            addKeyword(command.attributes['parameter'].strip(), countKeywordRows(), newId);
            $('parameter').value = '';
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return false;
        }
    },
    updateKeyword: {
        render: function (command) {
            return '<b>Edit</b> keyword alert: <b>' + command.attributes['oldParameter'] + '</b> -> <b>' + command.attributes['parameter'] + '</b>';
        },
        commandRecorded: function (command) {
            var selectedID = command.attributes['selectedID'];
            if (!command.attributes.oldParameter) {
                command.attributes.oldParameter = findKeywordParameter(selectedID);
            }
            var parameter = command.attributes['parameter'];
            updateKeyword(selectedID, parameter);
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID;
        },
        replace: function(existing, newCommand, commands) {
            nullifyExisting(existing, newCommand, commands);
            newCommand.attributes['oldParameter'] = existing.attributes['oldParameter'];
            commands.push(newCommand);
        }
    },
    updateKeywordFrequency: {
        render: function (command) {
            var selectedID = command.attributes['selectedID'];
            return '<b>Set frequency</b> for ' + command.attributes['keyword'] + ' to <b>' + command.attributes['newFrequency'] + '</b>';
        },
        validate: function(command, commands) {
            return command.attributes['newFrequency'] != command.attributes['oldFrequency'];
        },
        commandRecorded: function (command) {
            // record keyword to be able to render it properly
            var selectedID = command.attributes['selectedID'];
            command.attributes['keyword'] = findKeywordParameter(selectedID);
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID && existing.attributes.newFrequency != newCommand.attributes.newFrequency;
        },
        replace: nullifyExisting
    },
    deleteKeyword: {
        render: function (command) {
            return '<b>Delete</b> keyword alert for <b>' + command.attributes['keyword'] + '</b>';
        },
        commandRecorded: function (command) {
            var selectedID = command.attributes['selectedID'];
            command.attributes.keyword = findKeywordParameter(selectedID);
            deleteKeyword(selectedID);
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return false;
        }
    },
    onOffCategories: {
        render: function (command) {
            return getTurnOnOffString(command) + ' category alerts';
        },
        commandRecorded: function (command) {
            switchCategories(command.attributes['onOff']);
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.onOff ^ newCommand.attributes.onOff;
        },
        replace: nullifyExisting
    },
    updatePreset: {
        render: function (command) {
            var selectedID = command.attributes['selectedID'];
            return getTurnOnOffString(command) + ' preset alert: <b>' + presetAlertNames[selectedID] + '</b>';
        },
        commandRecorded: function (command) {
            switchPresetAlert(command.attributes['onOff'], command.attributes['selectedID']);
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID && existing.attributes.onOff ^ newCommand.attributes.onOff;
        },
        replace: nullifyExisting
    },
    updatePresetFrequency: {
        render: function (command) {
            var selectedID = command.attributes['selectedID'];
            return '<b>Set frequency</b> for ' + presetAlertNames[selectedID] + ' to <b>' + command.attributes['newFrequency'] + '</b>';
        },
        validate: function(command, commands) {
            return command.attributes['newFrequency'] != command.attributes['oldFrequency'];
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID && existing.attributes.newFrequency != newCommand.attributes.newFrequency;
        },
        replace: nullifyExisting
    },
    updateCategoriesFrequency: {
        render: function (command) {
            var selectedID = command.attributes['selectedID'];
            return '<b>Set frequency</b> for categories alert to <b>' + command.attributes['newFrequency'] + '</b>';
        },
        validate: function(command, commands) {
            return command.attributes['newFrequency'] != command.attributes['oldFrequency'];
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID && existing.attributes.newFrequency != newCommand.attributes.newFrequency;
        },
        replace: nullifyExisting
    },
    categorySelected: {
        render: function (command) {
            return getSelectedString(command) + ' category <b>' + command.attributes['name'] + '</b>';
        },
        commandRecorded: function (command, checkbox) {
            var name = checkbox.nextSibling.nodeValue;
            name = name.substring(2).strip().escapeHTML();
            command.attributes['name'] = name;
            updateCategoryHighlighting(checkbox, command.attributes['isOn']);
        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID && existing.attributes.isOn ^ newCommand.attributes.isOn;
        },
        replace: nullifyExisting
    },
    taxonomySelected: {
        render: function (command) {
            return getSelectedString(command) + ' category <b>' + command.attributes['name'] + '</b>';
        },
        commandRecorded: function (command, option) {
            var name = option.text;
            name = name.strip().escapeHTML();
            command.attributes['name'] = name;

        },
        shouldReplaceExistingCommand: function(existing, newCommand) {
            return existing.name == newCommand.name && existing.attributes.selectedID == newCommand.attributes.selectedID && existing.attributes.isOn ^ newCommand.attributes.isOn;
        },
        replace: nullifyExisting
    }
};

var bdAlerts = null;

var lastGeneratedId = 1;

function generateId() {
    return 'gen-' + lastGeneratedId++;
}


// check that user is signed up before sending command.
function execute(command, attributes, source) {
    if (checkSigned()) {
        recordCommand(command, attributes, source);
    }
}

function recordCommand(name, attributes, source) {
    escapeHashValues(attributes);
    var command = createCommand(name, attributes);
    addToPendingCommands(command, source);
    updateBalloon();
}

function escapeHashValues(attributes) {
    $H(attributes).keys().each(function(key) {
        var value = attributes[key];
        if (value != null && value.escapeHTML) {
            attributes[key] = value.escapeHTML();
        }
    });
}

function addToPendingCommands(command, source) {
    var methods = commandRegistry[command.name];
    var commands = getAlerts().pendingCommands;

    if (!methods.validate || methods.validate(command, commands)) {
        var existing = methods.shouldReplaceExistingCommand && $A(commands).find(function (existing) {
            return methods.shouldReplaceExistingCommand(existing, command);
        });
        if (existing && methods.replace) {
            methods.replace(existing, command, commands);
            getAlerts().pendingCommands = commands.compact();
        } else {
            commands.push(command);
        }
        if (methods.commandRecorded) {
            methods.commandRecorded(command, source);
        }
    }
}

// initialize alerts data structure if neccessary.
function getAlerts() {
    if (bdAlerts == null) {
        bdAlerts = {};
        bdAlerts.pendingCommands = $A([]);
    }
    return bdAlerts;
}

function createCommand(name, attributes) {
    return {name: name, attributes: attributes};
}

function findKeywordParameter(id) {
    var td = $(createKeywordRowId(id)).getElementsByTagName('td')[1];
    return td.getElementsByTagName('b')[0].innerHTML;
}

function updateBalloon() {
    var list = $('commandsList');
    list.innerHTML = '';
    var balloon = $('balloon');
    var commands = $A(getAlerts().pendingCommands);
    if (commands.size() > 0) {
        commands.each(function (command) {
            var item = document.createElement('li');
            item.innerHTML = commandRegistry[command.name].render(command);
            list.appendChild(item);
        });
        balloon.show();
    } else {
        balloon.hide();
    }
}

// send command to the server asynchronously.
// server should mark content as javascript and it will executed when successful response is received.
function sendCommand(name, attributes) {
    escapeHashValues(attributes);
    var url = '/AlertsUpdate.do?command=' + name;
    new Ajax.Request(url, {
        method: 'post',
        parameters: attributes
    });
}

function addKeyword(keyword, rowNumber, id) {
    var row = $('keywordRowTemplate').getElementsByTagName('tr')[0];
    row = row.cloneNode(true);
    row = $(row);
    row.className = getRowClass(rowNumber);
    row.id = createKeywordRowId(id);

    setupButtonBackground(row, rowNumber);

    var cells = row.getElementsByTagName('td');

    var td = cells[0];
    var a = td.getElementsByTagName('a')[0];
    a.alertId = id;
    a.isAlertActive = true;

    td = cells[1];
    keywordUpdateInCell(td, keyword);

    td = cells[2];

    td.alertId = id;
    td.frequencyValue = 'Weekly';
    // default frequency for new keyword alerts

    var daily = td.getElementsByTagName('input')[0];
    daily.name = id;

    var weekly = td.getElementsByTagName('input')[1];
    weekly.name = id;
    weekly.checked = true;

    td = cells[4];
    td.getElementsByTagName('a')[0].onclick = function () {
        execute('deleteKeyword', {selectedID: id});
        return false;
    }

    var body = $('keywordAlertsTable').tBodies[0];
    body.appendChild(row);
    $(body.getElementsByTagName('tr')[1]).hide();
}

function resetRowStyles(table) {
    table = $(table);
    var rows = $A(table.tBodies[0].getElementsByTagName('tr'));
    rows.shift();
    rows.shift();
    rows.each(function (tr, index) {
        tr.className = getRowClass(index);
        setupButtonBackground(tr, index);
    })
}

function setupButtonBackground(row, rowNumber) {
    var image = row.getElementsByTagName('img')[0];
    image.src = image.src.replace('_' + getButtonBackgroundName(rowNumber - 1), '_' + getButtonBackgroundName(rowNumber));
}

function getRowClass(rowNumber) {
    return (rowNumber % 2 == 0) ? 'alertsRowA' : 'alertsRowB';
}

function getButtonBackgroundName(rowNumber) {
    return (rowNumber % 2 == 0) ? 'bg1' : 'bg2';
}

function deleteKeyword(id) {
    $(createKeywordRowId(id)).remove();
    var body = $('keywordAlertsTable').tBodies[0];
    var rows = body.getElementsByTagName('tr');
    if (rows.length <= 2) {
        $(rows[1]).show();
    }
    resetRowStyles('keywordAlertsTable');
}

function createKeywordRowId(id) {
    return 'keywordRow-' + id;
}

function switchKeyword(id, isOn) {
    var td = $(createKeywordRowId(id)).getElementsByTagName('td')[0];
    switchButtonImage(td, isOn);
}

function countKeywordRows() {
    return $('keywordAlertsTable').tBodies[0].getElementsByTagName('tr').length;
}

function updateKeyword(id, keywords) {
    var td = $(createKeywordRowId(id)).getElementsByTagName('td')[1];
    keywordUpdateInCell(td, keywords);
    var span = td.getElementsByTagName('span')[0];
    $(span).hide();
    var b = td.getElementsByTagName('b')[0];
    $(b).show();
}

function makeKeywordEditable(rowId) {
    var td = $(rowId).getElementsByTagName('td')[1];
    var b = td.getElementsByTagName('b')[0];
    var keyword = b.innerHTML;
    $(b).hide();
    var span = td.getElementsByTagName('span')[0];
    span.getElementsByTagName('input')[0].value = keyword;
    $(span).show();
}

function keywordUpdateInCell(td, keyword) {
    td.getElementsByTagName('b')[0].innerHTML = keyword;
    var a = td.getElementsByTagName('a')[0];
    a.href = '/find-premium-domains/search-results.jsp?keywords=' + keyword;
}

function userUpdated(firstName, lastName, email) {
    showValidationErrors([]);

    $('currentUser').innerHTML = firstName + ' ' + lastName + ' - ' + email;
    $('oldEmail').value = email;
    updateTrustedComputer(true);
    // todo: call this only when there is no such cookie in the browser, so that it wouldn't change user settings for this computer.
    $('editUserTable').hide();
    $('cancelLinkSpan').hide();
    $('editLinkSpan').show();
}

function checkSigned() {
    var email = $F('oldEmail');
    if (email == null || email.length == 0) {
        alert('In order to make your alert selections you first need to enter your name and email.\n' +
              'Once you have entered your information, make your alert selections and click the "Update" button next to your email.');
        return false;
    }

    return true;
}

function switchCategories(isOn) {
    var td = $('categoriesAlertTable').getElementsByTagName('tr')[1].getElementsByTagName('td')[0];
    switchButtonImage(td, isOn);
}

function switchButtonImage(td, isOn) {
    var a = td.getElementsByTagName('a')[0];
    var image = a.getElementsByTagName('img')[0];
    if (isOn) {
        image.src = image.src.replace('_red_off_', '_green_on_');
    } else {
        image.src = image.src.replace('_green_on_', '_red_off_');
    }
    a.isAlertActive = isOn;
}

function switchPresetAlert(isOn, alertId) {
    var tr = $(alertId);
    var td = tr.getElementsByTagName('td')[0];
    switchButtonImage(td, isOn);
}

function updateCategoryHighlighting(checkbox, isOn) {
    checkbox.parentNode.className = isOn ? 'category-checkbox-selected' : 'category-checkbox';
}

function goUpdate(mthd, oOff, id) {
    if (mthd == null || mthd != 'signup')
        if (!checkSigned())
            return false;

    document.forms[0].method.value = mthd;
    document.forms[0].onOff.value = oOff;
    document.forms[0].selectedID.value = id;
    //        	alert('mthd=' + mthd);

    return true;
}

function updateTrustedComputer(trustedComputer) {
    $A(document.getElementsByName('trustedComputer')).each(function (element) {
        element.checked = (element.value == 'true') ^ !trustedComputer;
    });
}

function nullifyExisting(existing, newCommand, commands) {
    var index = commands.indexOf(existing);
    if (index != -1) {
        commands[index] = null;
    }
}

function getPresetAlertsRows(alertSection) {
    var rows = $A($(alertSection).getElementsByTagName('tr'));
    rows.shift();
    return rows;
}

function getTurnOnOffString(command) {
    var onOff = command.attributes['onOff'] ? 'On' : 'Off';
    return 'Turn <b>' + onOff + '</b>';
}

function getSelectedString(command) {
    var choice = command.attributes['isOn'] ? 'Select' : 'Unselect';
    return '<b>' + choice + '</b>';
}

function saveChanges() {
    var commands = getAlerts().pendingCommands;
    var xml = '<alerts-changes-batch email="' + $F('oldEmail') + '">\n';
    xml += renderCommands(commands);
    xml += '</alerts-changes-batch>\n';

    var url = '/AlertsUpdate.do?command=saveChangesBatch';
    new Ajax.Request(url, {
        method: 'post',
        parameters: {oldEmail: $F('oldEmail'), xml: xml}
    });
}

function renderCommands(commands) {
    var xml = '';
    $A(commands).each(function(command) {
        xml += '<command name="' + command.name + '">\n';
        xml += renderAttributes(command.attributes);
        xml += '</command>\n';
    });
    return xml;
}

function renderAttributes(attributes) {
    var xml = '';
    $H(attributes).each(function(pair) {
        xml += '<attribute name="' + pair.key + '">';
        if (pair.value != null) {
            xml += pair.value;
        }
        xml += '</attribute>\n';
    });
    return xml;
}

function cancelChanges() {
    window.location = '/alerts/alerts-manager.jsp';
}

function onCategoryClick(checkbox) {
    execute('categorySelected', {selectedID: checkbox.value, isOn: checkbox.checked, frequency: getAlertFrequency('CategoriesFrequency'), isActive: isCategoryAlertsActive()}, checkbox);
    return true;
}

function getAlertFrequency(id) {
    var frequencyCell = $('frequency-cell-' + id);
    return frequencyCell ? frequencyCell.frequencyValue : null;
}

function isCategoryAlertsActive() {
    var td = $('categoriesAlertTable').getElementsByTagName('tr')[1].getElementsByTagName('td')[0];
    var a = td.getElementsByTagName('a')[0];
    return a.isAlertActive;
}

// pop up Terms of Use
function openHelp() {
	window.open("alerts-phase-questions-pop.jsp","doTOU","toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=1,resizable=1,width=500,height=450,left=100,top=100,marginwidth=0, marginheight=0");
	return false;
}

function onLvl1Change(){
	loadLevel2CategoryList();
	var lvl1 = document.getElementsByName('l1')[0];
	createCommandsForList(lvl1);
	onLvl2Change();
}

function createCommandsForList(listObj){
	var commands = getAlerts().pendingCommands;
	for (var i = 1; i < listObj.options.length; i++) {
		var option = listObj.options[i];
		var existing=false;
		if(commands){
			commands.each(function (command) {
				if(command){
        			if(command.attributes['name'] == option.text){
						existing=true;//command.attributes.isOn ^ option.selected;
					}
				}
    		});
		}
		if((!existing && option.selected) || (existing && !option.selected)){
			execute('taxonomySelected',
				{selectedID: option.value, isOn: option.selected,
					frequency: getAlertFrequency('CategoriesFrequency'),
					isActive: isCategoryAlertsActive()}, option);
		}
	}
}
function onLvl2Change(){
	var lvl2 = document.getElementsByName('l2')[0];
	if(lvl2.options.length == 0) return;
	if (lvl2.options[0].selected){
    	for (var i = 1; i < lvl2.options.length; i++) {
    		lvl2.options[i].selected = false;
    	}
    }
	createCommandsForList(lvl2);
}

function showValidationErrors(errors) {
    try {
        var errorsDiv = $('user-update-errors');
        if (errors.length > 0) {
            var ul = errorsDiv.getElementsByTagName('ul')[0];
            if (ul) {
                $A($(ul).childNodes).each(Element.remove);
                for (var i = 0; i < errors.length; i++) {
                    var li = document.createElement('li');
                    li.appendChild(document.createTextNode(errors[i]));
                    ul.appendChild(li);
                }
            }
            errorsDiv.show();
        } else {
            errorsDiv.hide();
        }
    } catch(ex) {
        alert('Error: ' + ex);
    }
}
