/*
  Geopedia system backing code
*/

var gp = new Object; // Namespace
var yui = YAHOO.util; // alias

// Package globals
// gp.author_ids will be initted with IDs of authors if this is a view

// How far from the byline should the hovering author info box appear?
gp.AUTHOR_BOX_X_OFFSET = 100;
gp.AUTHOR_BOX_Y_OFFSET = -50;

// How far from the link should the experst list appear?
gp.EXPERTS_LIST_X_OFFSET = 0;
gp.EXPERTS_LIST_Y_OFFSET = 0;


//----------------------------------------------------------------
//                       Page Init
//----------------------------------------------------------------

gp.initialize = function() {
    gp.setupTextileHelp();
    gp.setupVersionBars();
    gp.setupNewEntryLink();
    gp.setupAuthorBoxes();
    gp.setupSuggestionBox();
    gp.setupQuestionBox();
    gp.setupLinkBox();
    gp.setupExpertsLink();
    gp.firstParagraphHack();
}
form.safeInit(gp.initialize);

//----------------------------------------------------------------
//                       Helpers
//----------------------------------------------------------------
gp.ignoreEvent = function(evt) {
    yui.Event.preventDefault(evt);
}

//----------------------------------------------------------------
//                       Textile Help
//----------------------------------------------------------------
gp.setupTextileHelp = function() {
    var showlink = new yui.Element('textile-link-show');
    if (showlink) {
        showlink.addListener('click', gp.toggleTextileHelp);
        var hidelink = new yui.Element('textile-link-hide');
        hidelink.addListener('click', gp.toggleTextileHelp);
        var hidelink2 = new yui.Element('textile-link-hide2');
        hidelink2.addListener('click', gp.toggleTextileHelp);
    }
};

gp.toggleTextileHelp = function(evt) {
    var tgtelem = yui.Event.getTarget(evt);

    var showlink = new yui.Element('textile-link-show');
    var hidelink = new yui.Element('textile-link-hide');
    var helpdiv  = new yui.Element('textile-quickref');

    if (tgtelem.id == 'textile-link-show') {
        yui.Event.preventDefault(evt);
        showlink.setStyle('display', 'none');
        hidelink.setStyle('display', 'inline');
        helpdiv.setStyle('display', 'block');
    } else if (tgtelem.id == 'textile-link-hide' || tgtelem.id == 'textile-link-hide2') {
        yui.Event.preventDefault(evt);
        showlink.setStyle('display', 'inline');
        hidelink.setStyle('display', 'none');
        helpdiv.setStyle('display', 'none');        
    }
}


//----------------------------------------------------------------
//                   Version Selectors
//----------------------------------------------------------------
gp.setupVersionBars = function() {
    // Look for 'show versions' links
    var links = yui.Dom.getElementsByClassName('version-bar-link', 'a');
    for (var l = 0; l < links.length; l++) {
        var link = new yui.Element(links[l].id);
        link.addListener('click', gp.ignoreEvent);
        link.addListener('mouseover', gp.showVersionBar);

        var section_id = gp.sectionIdFromElementId(link.get('id'));

        var close = new yui.Element('version-bar-close-' + section_id);
        close.addListener('click', gp.hideVersionBar);
    }
}

gp.sectionIdFromElementId = function(id) {
    // ID of link should end in section ID
    var parts = id.split('-');
    var section_id = parts[parts.length - 1];
    return section_id;
}

gp.showVersionBar = function(evt) {
    var rcvr = yui.Event.getTarget(evt);
    var section_id = gp.sectionIdFromElementId(rcvr.id);
    var bar = new yui.Element('version-bar-div-' + section_id);
    bar.setStyle('visibility', 'visible');
}


gp.hideVersionBar = function(evt) {
    yui.Event.preventDefault(evt);
    var rcvr = yui.Event.getTarget(evt);

    var section_id = gp.sectionIdFromElementId(rcvr.id);
    if (! section_id) { return; }
    var bar = new yui.Element('version-bar-div-' + section_id);

    bar.setStyle('visibility', 'hidden');

}

//----------------------------------------------------------------
//                      Make New Entry Link
//----------------------------------------------------------------
gp.makeNewEntry = function(evt) {
    gp.ignoreEvent(evt);

    // Ask for new entry name
    var rawtitle = window.prompt("Enter the name of the new GeoPedia (spaces permitted):");
    if (!rawtitle) { return; }
    var url = '/geopedia/' + gp.entry_title2url(rawtitle) + '/new_entry/?entry_title=' + escape(rawtitle);
    window.location = url;
}

gp.setupNewEntryLink = function() {
    var link = new yui.Element('gp_new_entry_link');
    if (link) {
        link.addListener('click', gp.makeNewEntry);
    }
}

gp.entry_title2url = function (title) {
    var url = title;

    // Delete leading and trailing spaces
    url = url.replace(/^\s*/g, '');
    url = url.replace(/\s*$/g, '');

    // Replace spaces with underscores
    url = url.replace(/\s/g, '_');

    // Delete EVERYTHING other than letters, numbers, and underscores
    url = url.replace(/[^\w\d]/g, '');

    return url;
}


//----------------------------------------------------------------
//                       Author Boxes
//----------------------------------------------------------------
gp.setupAuthorBoxes = function() {

    // This should be set within the page
    if (!gp.author_ids) { return; }

    for (var i=0; i < gp.author_ids.length; i++) {
        var id = gp.author_ids[i];

        // Wire up close button for this author box
        yui.Event.addListener('author_box_close_' + id,   'click', gp.hideAuthorBox);
        
        // Find all links to this author box
        // they will have the class 'gp_author_link_123' with 123= author_id
        var links = yui.Dom.getElementsByClassName('gp_author_link_' + id, 'a');
        for (var l = 0; l < links.length; l++) {
            yui.Event.addListener(links[l].id, 'click', gp.showAuthorBox);
        }
    }
}

gp.authorIdFromElementId = function(id) {
    // ID of link should end in author ID
    var parts = id.split('_');
    var author_id = parts[parts.length - 1];
    return author_id;
}

gp.hideAuthorBox = function(evt) {
    yui.Event.preventDefault(evt);
    var rcvr = yui.Event.getTarget(evt);
    var author_id = gp.authorIdFromElementId(rcvr.id);
    gp.hideAuthorBoxById(author_id);
}

gp.hideAuthorBoxById = function(author_id) {
    var author_box = new yui.Element('author_box_' + author_id);
    author_box.setStyle('display', 'none');
}

gp.hideAllAuthorBoxes = function() {
    if (!gp.author_ids) { return; }

    for (var i=0; i < gp.author_ids.length; i++) {
        gp.hideAuthorBoxById(gp.author_ids[i]);
    }
}

gp.showAuthorBox = function(evt) {
    yui.Event.preventDefault(evt);
    var rcvr = yui.Event.getTarget(evt);

    // Hide all other boxes
    gp.hideAllAuthorBoxes();

    // Receiver's ID should be of the form author_link_AID_SID
    var parts = rcvr.id.split('_');
    var author_id = parts[parts.length - 2];
    var section_id = parts[parts.length - 1];

    var author_box_id = 'author_box_' + author_id;
    var byline_id = 'byline_' + section_id;

    // Reveal - must happen before reposition
    var author_box = new yui.Element(author_box_id);
    author_box.setStyle('display', 'block');

    // Position the box near the byline
    var pos = yui.Dom.getXY(byline_id);
    pos = [pos[0] + gp.AUTHOR_BOX_X_OFFSET, pos[1] + gp.AUTHOR_BOX_Y_OFFSET];
    yui.Dom.setXY(author_box_id, pos);
    
}

//----------------------------------------------------------------
//                       Suggestion Box
//----------------------------------------------------------------
gp.setupSuggestionBox = function() {

    // Setup each suggestion link to show the suggestion box
    var links = yui.Dom.getElementsByClassName('gp_suggest_link', 'a');
    for (var l=0; l < links.length; l++) {
        yui.Event.addListener(links[l].id, 'click', gp.showSuggestionBox);
    }

    // Install handlers for the suggestion box itself
    form.monitorButton('suggest_submit', ['suggest_text', 'suggest_email', 'suggest_name']);
    yui.Event.addListener('suggest_submit', 'click', gp.suggestSubmit);
    yui.Event.addListener('suggest_cancel', 'click', gp.suggestCancel);
}

gp.showSuggestionBox = function(evt) {
    yui.Event.preventDefault(evt);

    // If the user clicked on another link, be sure to re-display it
    var old_section_id = document.getElementById('suggest_section').value;
    if (old_section_id) {
        yui.Dom.setStyle('section_links_' + old_section_id, 'display', 'block');
    }

    // Clear the form
    gp.suggestReset();
    
    // Move the suggestion box into the section's formbox
    var link = yui.Event.getTarget(evt);
    var section_id = gp.sectionIdFromSuggestLinkId(link.id);

    var formbox = document.getElementById('section_forms_' + section_id);
    var sbox = document.getElementById('suggest_div');
    formbox.appendChild(sbox);

    // Set the section in the suggestion box
    var ssection = document.getElementById('suggest_section');
    ssection.value = section_id;

    // If a user is logged in, pre-populate the form
    if (sso.user) {
        var sname = document.getElementById('suggest_name');
        sname.value = sso.user.first_name + ' ' + sso.user.last_name;
        var semail = document.getElementById('suggest_email');
        semail.value = sso.user.email;
        var ssso_id = document.getElementById('suggest_sso_id');
        ssso_id.value = sso.user.sso_id;
    }

    // Hide the section links
    yui.Dom.setStyle('section_links_' + section_id, 'display', 'none');

    // Show the suggestion box
    yui.Dom.setStyle(sbox, 'display', 'block');

}

gp.sectionIdFromSuggestLinkId = function(id) {
    // ID of link should end in section ID
    var parts = id.split('_');
    var section_id = parts[parts.length - 1];
    return section_id;
}

gp.suggestReset = function() {
    var sform = document.getElementById('suggest_form');
    sform.reset();
    form.updateCharacterLimit('suggest_text');
}

gp.suggestCancel = function(evt) {
    yui.Event.preventDefault(evt);

    // Hide the suggestion form
    var sbox = document.getElementById('suggest_div');    
    yui.Dom.setStyle(sbox, 'display', 'none');
    
    // Clear the form
    gp.suggestReset();

    // Put it back in the garage
    var garage = document.getElementById('section_form_garage');
    garage.appendChild(sbox);


    // Show the section links area again
    var section_id = document.getElementById('suggest_section').value;
    yui.Dom.setStyle('section_links_' + section_id, 'display', 'block');

}

gp.suggestSubmit = function(evt) {
    var suggest_form = document.getElementById('suggest_form');
    suggest_form.submit();
}


//----------------------------------------------------------------
//                       Ask a Question
//----------------------------------------------------------------
gp.setupQuestionBox = function() {

    // Setup each question link to show the question box
    var links = yui.Dom.getElementsByClassName('gp_question_link', 'a');
    for (var l=0; l < links.length; l++) {
        yui.Event.addListener(links[l].id, 'click', gp.showQuestionBox);
    }

    // Install handlers for the question box itself
    form.monitorButton('question_submit', ['question_text', 'question_email', 'question_name']);
    yui.Event.addListener('question_submit', 'click', gp.questionSubmit);
    yui.Event.addListener('question_cancel', 'click', gp.questionCancel);
}

gp.showQuestionBox = function(evt) {
    yui.Event.preventDefault(evt);

    // If the user clicked on another link, be sure to re-display it
    var old_section_id = document.getElementById('question_section').value;
    if (old_section_id) {
        yui.Dom.setStyle('section_links_' + old_section_id, 'display', 'block');
    }

    // Clear the form
    gp.questionReset();
    
    // Move the question box into the section's formbox
    var link = yui.Event.getTarget(evt);
    var section_id = gp.sectionIdFromQuestionLinkId(link.id);

    var formbox = document.getElementById('section_forms_' + section_id);
    var qbox = document.getElementById('question_div');
    formbox.appendChild(qbox);

    // Set the section in the question box
    var qsection = document.getElementById('question_section');
    qsection.value = section_id;

    // If a user is logged in, pre-populate the form
    if (sso.user) {
        var qname = document.getElementById('question_name');
        qname.value = sso.user.first_name + ' ' + sso.user.last_name;
        var qemail = document.getElementById('question_email');
        qemail.value = sso.user.email;
        var qsso_id = document.getElementById('question_sso_id');
        qsso_id.value = sso.user.sso_id;
    }

    // Hide the section links
    yui.Dom.setStyle('section_links_' + section_id, 'display', 'none');

    // Show the question box
    yui.Dom.setStyle(qbox, 'display', 'block');

}

gp.sectionIdFromQuestionLinkId = function(id) {
    // ID of link should end in section ID
    var parts = id.split('_');
    var section_id = parts[parts.length - 1];
    return section_id;
}

gp.questionReset = function() {
    var qform = document.getElementById('question_form');
    qform.reset();
    form.updateCharacterLimit('question_text');
}

gp.questionCancel = function(evt) {
    yui.Event.preventDefault(evt);

    // Hide the question form
    var qbox = document.getElementById('question_div');    
    yui.Dom.setStyle(qbox, 'display', 'none');
    
    // Clear the form
    gp.questionReset();

    // Put it back in the garage
    var garage = document.getElementById('section_form_garage');
    garage.appendChild(qbox);

    // Show the section links area again
    var section_id = document.getElementById('question_section').value;
    yui.Dom.setStyle('section_links_' + section_id, 'display', 'block');
}

gp.questionSubmit = function(evt) {
    var question_form = document.getElementById('question_form');
    question_form.submit();
}

//----------------------------------------------------------------
//                       Submit a Link
//----------------------------------------------------------------
gp.setupLinkBox = function() {

    // Setup each link link to show the link box
    var links = yui.Dom.getElementsByClassName('gp_link_link', 'a');
    for (var l=0; l < links.length; l++) {
        yui.Event.addListener(links[l].id, 'click', gp.showLinkBox);
    }

    // Install handlers for the link box itself
    form.monitorButton('link_submit', ['link_text', 'link_link', 'link_email', 'link_name']);
    yui.Event.addListener('link_submit', 'click', gp.linkSubmit);
    yui.Event.addListener('link_cancel', 'click', gp.linkCancel);
}

gp.showLinkBox = function(evt) {
    yui.Event.preventDefault(evt);

    // If the user clicked on another link, be sure to re-display it
    var old_section_id = document.getElementById('link_section').value;
    if (old_section_id) {
        yui.Dom.setStyle('section_links_' + old_section_id, 'display', 'block');
    }

    // Clear the form
    gp.linkReset();
    
    // Move the link box into the section's formbox
    var link = yui.Event.getTarget(evt);
    var section_id = gp.sectionIdFromLinkLinkId(link.id);

    var formbox = document.getElementById('section_forms_' + section_id);
    var qbox = document.getElementById('link_div');
    formbox.appendChild(qbox);

    // Set the section in the link box
    var qsection = document.getElementById('link_section');
    qsection.value = section_id;

    // If a user is logged in, pre-populate the form
    if (sso.user) {
        var qname = document.getElementById('link_name');
        qname.value = sso.user.first_name + ' ' + sso.user.last_name;
        var qemail = document.getElementById('link_email');
        qemail.value = sso.user.email;
        var qsso_id = document.getElementById('link_sso_id');
        qsso_id.value = sso.user.sso_id;
    }

    // Hide the section links
    yui.Dom.setStyle('section_links_' + section_id, 'display', 'none');

    // Show the link box
    yui.Dom.setStyle(qbox, 'display', 'block');

}

gp.sectionIdFromLinkLinkId = function(id) {
    // ID of link should end in section ID
    var parts = id.split('_');
    var section_id = parts[parts.length - 1];
    return section_id;
}

gp.linkReset = function() {
    var qform = document.getElementById('link_form');
    qform.reset();
    form.updateCharacterLimit('link_text');
}

gp.linkCancel = function(evt) {
    yui.Event.preventDefault(evt);

    // Hide the link form
    var qbox = document.getElementById('link_div');    
    yui.Dom.setStyle(qbox, 'display', 'none');
    
    // Clear the form
    gp.linkReset();

    // Put it back in the garage
    var garage = document.getElementById('section_form_garage');
    garage.appendChild(qbox);

    // Show the section links area again
    var section_id = document.getElementById('link_section').value;
    yui.Dom.setStyle('section_links_' + section_id, 'display', 'block');
}

gp.linkSubmit = function(evt) {
    var link_form = document.getElementById('link_form');
    link_form.submit();
}



//----------------------------------------------------------------
//                    First Paragraph Hack   
//----------------------------------------------------------------

// For reasons unknown, NGM insists that the first paragraph 
// of the first section have a different CSS style, and that the 
// navbox appear below it.
// Since the GeoPEdia content is written in Textile and rendered 
// on the fly, this is a bit of a pain on the server.  We thus do it here.

gp.firstParagraphHack = function() {
    // find first section
    var sections = yui.Dom.getElementsByClassName('gp_section_text', 'div', '');
    if (!sections.length) { return; }
    var first_section = sections[0];
    
    // Find first paragraph
    var para = yui.Dom.getFirstChildBy(first_section, function(node) { return node.nodeName == 'P'; });

    // Adjust CSS on first paragraph
    yui.Dom.addClass(para, 'gp_first_para');

    // Get a hold of the navbox
    var nav = yui.Dom.get('navbox');
    if (!nav) { return; }

    // Move the navbox to be after the first paragraph.
    yui.Dom.insertAfter(nav, para);

}

//----------------------------------------------------------------
//                    Experts Link
//----------------------------------------------------------------
gp.setupExpertsLink = function() {
    var link = yui.Dom.get('experts_link');
    if (!link) { return; }

    // Wire up show link
    yui.Event.addListener('experts_link', 'click', gp.showExpertsList);

    // Wire up close button
    yui.Event.addListener('experts_close', 'click', gp.hideExpertsList);
}


gp.hideExpertsList = function(evt) {
    yui.Event.preventDefault(evt);
    yui.Dom.setStyle('experts_list', 'display', 'none');
}

gp.showExpertsList = function(evt) {
    yui.Event.preventDefault(evt);
    yui.Dom.setStyle('experts_list', 'display', 'block');

    var pos = yui.Dom.getXY('experts_link');
    pos = [pos[0] + gp.EXPERTS_LIST_X_OFFSET, pos[1] + gp.EXPERTS_LIST_Y_OFFSET];
    yui.Dom.setXY('experts_list', pos);

}


