var g_handlers = new Array();
var g_popup_handlers = new Array();
var g_highlight;

function initialize()
{
    if (isLoggedIn())
    {
        if (g_editable)
            enableEdits();
        hideLoginWindow();
    }
    else showLoginWindow(); 

    window.parent.document.title = document.title;
}

function _escape(str)
{
  return encodeURIComponent(str); //escape(str);
}

function _unescape(str)
{
  return unescape(str);
}

function getSessionId()
{
    var user_cookie = getCookie('user');
    return (user_cookie != null) ? user_cookie.split(',')[1] : null;
}

function getUserId()
{
    var user_cookie = getCookie('user');
    return (user_cookie != null) ? user_cookie.split(',')[0] : null;
}

function getAuthString()
{
    return 'session=' + getSessionId();
}

function urlencode(str)
{
    var enc = _escape(str).replace(/\+/g, '%2b');
    return enc;
}

function loadFormValues(params, form)
{
    var i, n, j, m, node;

    n = form.elements.length;
    for (i = 0; i < n; i++)
    {
        node = form.elements[i];
        if (node.name) 
        {
            if (node.tagName.toLowerCase() == 'input' && node.type == 'checkbox')
            {
                if (node.checked)
                    params[node.name] = node.value;
            }
            else if (node.tagName.toLowerCase() == 'select')
            {
                m = node.options.length;
                for (j = 0; j < m; j++)
                    if (node.options[j].selected)
                        params[node.name] = node.options[j].value;
            }
            else 
            {
                params[node.name] = node.value;
            }
        }
    }
}

function addHandler(tagName, fn)
{
    g_handlers[tagName] = fn;
}

function addPopupHandler(tagName, fn)
{
    g_popup_handlers[tagName] = fn;
}

function getHandler(tagName)
{
    if (!g_handlers[tagName])
        return null;

    return g_handlers[tagName];
}

function getPopupHandler(tagName)
{
    if (!g_popup_handlers[tagName])
        return null;

    return g_popup_handlers[tagName];
}

function displayMessage(message)
{
    document.getElementById('message').innerHTML = message;
}

function displayError(message)
{
    document.getElementById('message').innerHTML = message;
    window.alert(message);
}

function showPopupWindow(pos)
{
    var popup = document.getElementById('popup');

    popup.style.left = (pos.x - 33) + 'px';
    popup.style.top = pos.y + 'px';
    popup.style.display = 'block';
}

function hidePopupWindow(pos)
{
    var popup = document.getElementById('popup');
    popup.style.display = 'none';
}

function getPopupWindow()
{
    return document.getElementById('popup_data');
}

function clearPopupWindow()
{
    var popup = getPopupWindow();
    while (popup.hasChildNodes())
        popup.removeChild(popup.firstChild);
}

function createCell(row)
{
    var cell = row.insertCell(-1);
    return cell;
}

function createRow(table)
{
    var row = table.insertRow(-1);
    return row;
}

function createFormRow(table, title)
{
    var row = createRow(table);
    var cell = createCell(row);
    cell.innerHTML = title;
    cell = createCell(row);

    return cell;
}

function createAnchor(href, caption)
{
    var anchor = document.createElement('a');
    anchor.href = href;
    anchor.innerHTML = caption;

    return anchor;
}

function createTextbox(name)
{
    var text = document.createElement('input');
    text.type = 'text';
    text.className = 'textbox';
    text.name = name;
    text.id = name;

    return text;
}

function createCheckbox(name, value)
{
    var inp = document.createElement('input');
    inp.type = 'checkbox';
    inp.className = 'checkbox';
    inp.name = name;
    if (value) inp.value = value;

    return inp;
}

function createPassword(name)
{
    var text = document.createElement('input');
    text.type = 'password';
    text.className = 'textbox';
    text.name = name;
    text.id = name;

    return text;
}

function createHidden(name)
{
    var text = document.createElement('input');
    text.type = 'hidden';
    text.name = name;

    return text;
}

function createButton(cap, submit)
{
    var but = document.createElement('input');
    but.type = (submit) ? 'submit' : 'button';
    but.className = 'button';
    but.value = cap;

    return but;
}

function createDropList(name)
{
    var list = document.createElement('select');
    list.name = name;
    list.id = name;

    return list;
}

function createOption(value, text)
{
    var opt = document.createElement('option');
    opt.value = value;
    opt.innerHTML = (text ? text : value);

    return opt;
}

function createSpan(id)
{
    var node = document.createElement('span');
    if (id) node.id = id;

    return node;
}

function createDiv(id, content)
{
    var node = document.createElement('div');
    if (id) node.id = id;
    if (content) node.innerHTML = content;

    return node;
}

function getHomePath()
{
    return g_path;
}

function getOwnerPath()
{
    return getHomePath() + '/' + g_owner;
}

function getCollPath()
{
    return getOwnerPath() + '/' + g_coll;
}

function getTitle(row)
{
    var kids = row.getElementsByTagName("span");
    var classes, i, j;

    for (i = 0; i < kids.length; i++)
    {
        classes = kids[i].className.split(/\s+/);
        for (j = 0; j < classes.length; j++)
            if (classes[j] == g_request)
                return kids[i].innerHTML;
    }
        
    return null;
}

function trim(str)
{
    return str.replace(/^\s*|\s*$/g, '');
}

function getCookie(name)
{
    var parts = document.cookie.split(';');
    var part;

    for (var i = 0; i < parts.length; i++)
    {
        part = parts[i];
        while (part.charAt(0) == ' ') part = part.substring(1, part.length);
        if (part.indexOf(name + '=') == 0) return part.substring(name.length + 1, part.length);
    }

    return null;
}

function resetGrouping(group)
{
    var cook_name = g_coll + '_prefs';
    var cook_value = getCookie(cook_name);

    if (cook_value == null)
    {
        cook_value = group;
    }
    else
    {
        var parts = _unescape(cook_value).split(',');

        parts[0] = group;
        cook_value = parts.join(',');
    }

    setCookie(cook_name, _escape(cook_value), 365);
}

function resetOrder(order)
{
    var cook_name = g_coll + '_prefs';
    var cook_value = getCookie(cook_name);
    var parts;

    if (cook_value == null)
    {
        parts = new Array(0, order);
    }
    else
    {
        parts = _unescape(cook_value).split(',');
        parts[(parts[0] * 1) + 1] = order;
    }

    cook_value = parts.join(',');
    setCookie(cook_name, _escape(cook_value), 365);
}

function groupBy(group)
{
    resetGrouping(group);
    window.location.reload();
}

function orderBy(order)
{
    resetOrder(order);
    window.location.reload();
}

function find(terms)
{
    resetGrouping(0);
    window.location = getCollPath() + '/find=' + urlencode(terms);
}

function setCookie(name, value, days)
{
    var date = new Date();
    date.setTime(date.getTime() + (days*24*3600*1000));
    document.cookie = name + '=' + value + '; expires=' + date.toGMTString() + '; path=' + getHomePath();
}

function handleResponse(request, param)
{
    if (request.readyState == 4)
    {
        animStop();

        if (request.status != 200)
        {
            var message = 'Problem with the last request';
            if (request.statusText) message += ': ' + request.statusText;
            displayError(message);
            return;
        }

        var xmlDoc = getXMLDocument(request);
        if (g_handlers[xmlDoc.documentElement.tagName])
        {
            hidePopupWindow();
            clearPopupWindow();

            if (g_handlers[xmlDoc.documentElement.tagName](xmlDoc, param))
                if (param.x && param.y) showPopupWindow(param);
        }
    }
}

function sendRequest(details, userData, dest)
{
    var req = new AjaxRequest();

    req.target = getHomePath() + '/' + ((dest) ? dest : g_coll) + '-h.php';
    req.params = details;
    req.userData = userData;
    req.onReady = onResponse;

    req.send();
}

function onResponse(request)
{
    animStop();

    var doc = request.xml;
    var tag = doc.documentElement.tagName;
    var handler;

    if (handler = getHandler(tag))
    {
        hidePopupWindow();
        clearPopupWindow();
        handler(request.xml, request.userData);
    }
}

function onFetched(request)
{
    animStop();

    var doc = request.xml;
    var tag = doc.documentElement.tagName;
    var handler;

    if (handler = getPopupHandler(tag))
    {
        hidePopupWindow();
        clearPopupWindow();

        handler(request.xml);
        showPopupWindow(request.userData);
    }
}

function fetch(node, e, key)
{
    var pos, query, key;

    e = e || window.event;

    if (e.pageX) pos = {x:e.pageX,y:e.pageY};
    else pos = {x:e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft,
                y:e.clientY + document.documentElement.scrollTop + document.body.scrollTop};

    var req = new AjaxRequest();

    req.target = getHomePath() + '/' + g_coll + '-h.php';
    req.onReady = onFetched;
    req.userData = pos;

    req.params = new Array();
    req.params["query"] = g_request;
    req.params["id"] = key;

    animGo(node);
    req.send();
}

function animStop()
{
    var ticker = document.getElementById('ticker');
    if (!ticker) return;
    ticker.parentNode.removeChild(ticker);
}

function animGo(node, first)
{
    animStop();

    var ticker = document.createElement('span');
    ticker.innerHTML = 'loading...';
    ticker.id = 'ticker';

    if (first) node.insertBefore(ticker, node.firstChild);
    else node.appendChild(ticker);
}

function isLoggedIn()
{
    return getCookie('user');
}

function login()
{
    var username = document.getElementById('login_uid').value;
    var password = document.getElementById('login_pwd').value;

    if (username.length < 1 || password.length < 1)
    {
        displayError('Bad username or password');
        return;
    }

    animGo(document.getElementById('signon'), true);

    var r = new Array();
    r["uid"] = username;
    r["pwd"] = password;

    sendRequest(r, username);
}

function isOwner()
{
    return g_owner == getUserId();
}

function logout()
{
    endEdit();

    setCookie('user', '', -1);

    disableEdits();
    showLoginWindow();
}

function onSignIn(xmlDoc, param)
{
    setCookie('user', 
        param + ',' + xmlDoc.getElementsByTagName('session')[0].firstChild.data, 14);

    hideLoginWindow();
    if (g_editable)
        enableEdits();
}

function enableEdits()
{
    if (!isOwner())
        return;

    var rows, row, link, span;
    rows = document.getElementById('rows');
    for (var i = 0; i < rows.childNodes.length; i++)
    {
        row = rows.childNodes[i];
        if (row.tagName && row.tagName.toLowerCase() == 'div')
            insertEditLinks(row);
    }

    var search_div = document.getElementById('search');
    link = createButton('Add');
    link.id = 'add_button';
    link.onclick = function() { add(); };

    search_div.insertBefore(link, search_div.firstChild);
}

function disableEdits()
{
    var rows, row, span, j, k, edits;

    j = 0;
    rows = document.getElementById('rows');

    for (var i = 0; i < rows.childNodes.length; i++)
    {
        row = rows.childNodes[i];
        if (row.tagName && row.tagName.toLowerCase() == 'div')
        {
            k = ++j % 2;
            if (row.className == 'row mod') 
                row.className = 'row row' + k;
 
           edits = row.getElementsByTagName('div');
            if (edits.length > 0)
                row.removeChild(edits[0]);
        }
    }

    var add_but = document.getElementById('add_button');
    if (add_but) 
        add_but.parentNode.removeChild(add_but);
}

function showLoginWindow()
{
    var signon = document.getElementById('signon');
    while (signon.hasChildNodes())
        signon.removeChild(signon.firstChild);

    var text;

    signon.appendChild(document.createTextNode('Username '));
    text = createTextbox('login_uid');
    signon.appendChild(text);
    
    signon.appendChild(document.createTextNode('Password '));
    text = createPassword('login_pwd');
    signon.appendChild(text);

    var a = document.createElement('a');
    a.href = 'javascript:login();';
    a.innerHTML = 'Sign in';
    signon.appendChild(a);

    var but = createButton('', true);
    signon.appendChild(but);
}

function hideLoginWindow()
{
    var signon = document.getElementById('signon');
    while (signon.hasChildNodes())
        signon.removeChild(signon.firstChild);

    var span;

    span = createSpan(null);
    span.className = 'ident';
    span.innerHTML = getCookie('user').split(',')[0];
    signon.appendChild(span);

    var a = document.createElement('a');
    a.href = 'javascript:logout();';
    a.innerHTML = 'Sign out';
    signon.appendChild(a);
}

function getModParams(modType, key)
{
    var r = new Array();

    r["session"] = getSessionId();
    r["coll"] = g_coll;
    if (modType != null) r["modify"] = modType;
    if (key != null) r["id"] = key;

    return r;
}

/* Editing */

function add()
{
    animGo(document.getElementById('signon'), true);
    sendRequest(getModParams("load", 0));
}

function remove(key)
{
    var node = document.getElementById(getRowId(key));

    if (!confirm('Are you sure you want to delete \'' + getTitle(node) + '\''))
        return;

    endEdit();
    animGo(node);
    sendRequest(getModParams("delete", key));
}

function edit(key)
{
    var node = document.getElementById(getRowId(key));
    animGo(node);
    sendRequest(getModParams("load", key));
}

function onLoad(xmlDoc, param)
{
    var editor, form, id, node;

    editor = createDiv('editor');
    form = document.createElement('form');
    editor.appendChild(form);

    id = xmlDoc.documentElement.getAttribute('id');
    if (id > 0 && !(node = document.getElementById(getRowId(id)))) return;
    endEdit();

    if (id > 0)
    {
        var cls = node.className.split(' ')[1];
        editor.className = cls;
        node.parentNode.insertBefore(editor, node.nextSibling);

        var hidden = createHidden('id');
        hidden.value = id;
        form.appendChild(hidden);
    }
    else
    {
        node = document.getElementById('rows');
        node.insertBefore(editor, node.firstChild);
    }

    disableEdits();

    var table = document.createElement('table');
    form.appendChild(table);

    editTheme(table, xmlDoc);

    // Buttons

    div = createDiv('buttons');
    editor.appendChild(div);

    button = createButton('OK');
    button.onclick = function() { onSaveChanges(form); }
    div.appendChild(button);

    button = createButton('Cancel');
    button.onclick = function() { onCancel(); }
    div.appendChild(button);
}

function onError(xmlDoc, param)
{
    displayError(xmlDoc.documentElement.firstChild.data);
}

function onDelete(xmlDoc, param)
{
    endEdit();

    var key = xmlDoc.documentElement.getAttribute('id');
    var row = document.getElementById(getRowId(key));

    // remove the row

    row.parentNode.removeChild(row);
    recolorRows();

    // update count

    var showing = document.getElementById('showing');
    var total = document.getElementById('total');

    showing.innerHTML--;
    total.innerHTML--;

    displayMessage('Deleted successfully');
}

function onUpdate(xmlDoc, param)
{
    enableEdits();
    endEdit();

    var coll, classes, field, i, r;
    var key = xmlDoc.documentElement.getAttribute('id');
    var row = document.getElementById(getRowId(key));

    // update the row

    coll = row.getElementsByTagName('span');
    for (i = 0; i < coll.length; i++)
    {
        classes = coll[i].className.split(' ');
        field = classes[0];

        coll[i].innerHTML = 
            (xmlDoc.getElementsByTagName(field)[0].firstChild) ? 
                xmlDoc.getElementsByTagName(field)[0].firstChild.data : '';
    }

    // reposition the row

    repositionRow(row);
    recolorRows(row);
    displayMessage('Updated successfully');
}

function insertEditLinks(row)
{
    var links, link, id;

    links = createDiv(null);
    links.className = 'cat link';
    row.insertBefore(links, row.firstChild);
    id = row.id.substring(1);

    link = document.createElement('a');
    link.href = 'javascript:edit(' + id + ');';
    link.innerHTML = 'Edit';
    link.onclick = function(event) { var e = window.event || event; e.cancelBubble=true; }; 
    links.appendChild(link);

    links.appendChild(document.createTextNode(' '));

    link = document.createElement('a');
    link.href = 'javascript:remove(' + id + ');';
    link.innerHTML = 'Delete';
    link.onclick = function(event) { var e = window.event || event; e.cancelBubble=true; }; 
    links.appendChild(link);
}

function getRowId(key)
{
    return 'r' + key;
}

function createDataRow(xmlDoc)
{
    var id, row, span, col;

    id = xmlDoc.documentElement.getAttribute('id');

    row = createDiv(getRowId(id));
    row.className = 'row row0';
    row.onclick = function(event) { var e = window.event || event; fetch(row, e, id); }

    span = createSpan();
    col = g_column_names[0];
    span.className = col + ' cat selected';
    span.innerHTML = 
        (xmlDoc.getElementsByTagName(col)[0].firstChild) ?
            xmlDoc.getElementsByTagName(col)[0].firstChild.data : '';

    row.appendChild(span);
    row.appendChild(document.createTextNode(' '));

    span = createSpan();
    col = g_column_names[1];
    span.className = col + ' cat';
    span.innerHTML = 
        (xmlDoc.getElementsByTagName(col)[0].firstChild) ?
            xmlDoc.getElementsByTagName(col)[0].firstChild.data : '';
    row.appendChild(span);

    insertEditLinks(row);

    return row;
}

function onInsert(xmlDoc, param)
{
    enableEdits();
    endEdit();

    // create and position the new row

    var row = createDataRow(xmlDoc);
    repositionRow(row);
    recolorRows(row);

    // update count

    var showing = document.getElementById('showing');
    var total = document.getElementById('total');

    showing.innerHTML++;
    total.innerHTML++;

    displayMessage('Added successfully');
}

function repositionRow(row)
{
    var i, s1, s2, coll1, coll2, coll3, parent;

    parent = document.getElementById('rows');
    coll1 = row.getElementsByTagName('span');
    s1 = coll1[0].innerHTML.toLowerCase();
    coll2 = parent.getElementsByTagName('div');

    row.className = 'row mod';

    for (i = 0; i < coll2.length; i++)
    {
        r = coll2[i];
        if (r == row) continue;

        coll3 = r.getElementsByTagName('span');

        if (coll3.length < 1) continue;
        s2 = coll3[0].innerHTML.toLowerCase();

        if (s2 > s1)
        {
            parent.insertBefore(row, r);
            return;
        }
    }

    parent.insertBefore(row, null);
}

function recolorRows(last)
{
    var coll, row, i, j, k, cls;

    j = 0;
    coll = document.getElementById('rows').childNodes;
    for (i = 0; i < coll.length; i++)
    {
        row = coll[i];
        if (row.tagName && row.tagName.toLowerCase() == 'div')
        {
            k = ++j % 2;
            cls = row.className.split(' ');
            if (cls[1] == 'row' + k) continue;
            else if (row != last) row.className = 'row row' + k;
        }
    }
}

function onSaveChanges(form)
{
    var action = 'insert';
    for (var i = 0; i < form.elements.length; i++)
        if (form.elements[i].name == 'id') { action = 'update'; break; }

    var params = getModParams(action);
    loadFormValues(params, form);

    sendRequest(params);
}

function onCancel()
{
    enableEdits();
    endEdit();
}

function getEditWindow()
{
    return document.getElementById('editor');
}

function endEdit()
{
    var editor = getEditWindow();

    if (!editor) return;

    editor.parentNode.removeChild(editor);
}

function formatDate(ddate)
{
    var months = Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
    var date = new Date();
    date.setTime(ddate * 1000);
    return months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear();
}

function onSearch(terms)
{
    terms = trim(terms);

    if (terms.length < 1)
    {
        window.alert('Please enter one or more search terms');
        return;
    }

    window.location = getCollPath() + '/find=' + urlencode(terms);
}

function onShowAll()
{
    window.location = getCollPath();
}

function getKeywordList(xmlDoc)
{
    if (!xmlDoc.getElementsByTagName('keywords')[0].firstChild)
        return null;

    var kydiv = createDiv('keywords');
    var span = createSpan();

    kydiv.appendChild(document.createTextNode('Keywords: '));
    var kywds = xmlDoc.getElementsByTagName('keywords')[0].firstChild.data.split(/\s+/);

    var i, n = kywds.length;
    for (var i = 0; i < n; i++)
    {
        link = document.createElement('a');
        link.href = "javascript:find('" + kywds[i].replace("'", "\'") + "');";
        link.innerHTML = kywds[i];
        span.appendChild(link);

        if (i < n - 1) span.appendChild(document.createTextNode(', '));
    }

    kydiv.appendChild(span);

    return kydiv;
}

addHandler('login', onSignIn);
addHandler('load', onLoad);
addHandler('update', onUpdate);
addHandler('insert', onInsert);
addHandler('delete', onDelete);
addHandler('error', onError);

