
var searchID    = 0;
var searchType  = "";
var authors     = null;
var orgs        = null;
var pages       = new Array();
var pane        = null;     // the current search pane object
var matchCount  = 0;
var pageSize    = 0;

// handlers and state for each search pane
var panes   =
    [
        {
            'appendCriteria' : function(label, value) { this.criteria = conjunctionize(this.criteria, label, value); }
        ,   'criteria' : ''
        ,   'clear' : function ()
            {
                var oldIndex = document.getElementById("SelectOrganization").selectedIndex;

                document.getElementById("SelectType").selectedIndex = 0;
                document.getElementById("TextTitle").value = "";
                document.getElementById("TextDescription").value = "";
                document.getElementById("SelectOrganization").selectedIndex = 0;
                document.getElementById("SelectAuthor").selectedIndex = 0;
                document.getElementById("TextAnyAuthor").value = "";
                document.getElementById("TextDateUploaded").value = "";
                document.getElementById("TextBeginDate").value = "";
                document.getElementById("TextEndDate").value = "";
                setFocus("SelectType");

                if (oldIndex != 0)
                    onOrganizationChange()
            }
        ,   'startSearch': function(p)
            {
                searchID++;
                searchType = "fielded";

                var arg0 = document.getElementById("SelectType").value;
                var arg1 = document.getElementById("TextTitle").value;
                var arg2 = document.getElementById("TextDescription").value;
                var arg3 = document.getElementById("SelectOrganization").value;
                var arg4 = document.getElementById("SelectAuthor").value;
                var arg5 = document.getElementById("TextDateUploaded").value;
                var arg6 = document.getElementById("TextBeginDate").value;
                var arg7 = document.getElementById("TextEndDate").value;
                var arg8 = document.getElementById("TextAnyAuthor").value;
                this.criteria   = '';

                this.appendCriteria('The publication is a', getSelectedText("SelectType"));
                this.appendCriteria('The title contains', arg1);
                this.appendCriteria('The description contains', arg2);
                this.appendCriteria('The author works for', getSelectedText("SelectOrganization"));
                this.appendCriteria('The primary author is', getSelectedText("SelectAuthor"));
                this.appendCriteria('One of the author names contains', arg8);
                this.appendCriteria('The document was uploaded in', arg5);

                if (arg6 != "")
                    this.appendCriteria('The document covers', arg6 + ' through ' + arg7);

                if (arg0 == "") arg0 = 0;
                if (arg3 == "") arg3 = 0;
                if (arg4 == "") arg4 = 0;

                if (arg5 != "")
                {
                    var re = /^(\d{1,2})\/(\d{4})$/;
                    re.exec(arg5);
                    arg5 = new Date(RegExp.$1 + '/1/' + RegExp.$2);
                }

                BPA.Pisces.Publication.Search.DocumentSearch.SearchByTextAndAuthorAndDate
                    (
                        arg0
                    ,   arg1
                    ,   arg2
                    ,   arg3
                    ,   arg4
                    ,   arg5
                    ,   arg6
                    ,   arg7
                    ,   arg8
                    ,   ''
                    ,   '+'
                    ,   p
                    ,   onSearchComplete
                    ,   onSearchError
                    ,   { 'pane' : panes[2], 'id' : searchID }
                    );

                return true;
            }
        ,   'validateSearch' : function()
            {
                var arg0    = document.getElementById("SelectType").value;
                var arg1    = document.getElementById("TextTitle").value;
                var arg2    = document.getElementById("TextDescription").value;
                var arg3    = document.getElementById("SelectOrganization").value;
                var arg4    = document.getElementById("SelectAuthor").value;
                var arg5    = document.getElementById("TextDateUploaded").value;
                var arg6    = document.getElementById("TextBeginDate").value;
                var arg7    = document.getElementById("TextEndDate").value;
                var arg8    = document.getElementById("TextAnyAuthor").value;

                if (arg0 + arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 == "")
                {
                    setFocus("TextTitle");
                    return "You must enter data for at least one of the search criteria";
                }

                if (arg5 != "" && !isValidMonthYear(arg5))
                {
                    setFocus("TextDateUploaded");
                    return "Upload month/year is not valid";
                }

                if (arg6 != "" && !isValidDate(arg6))
                {
                    setFocus("TextBeginDate");
                    return "Period beginning date is not a valid date";
                }

                if (arg7 != "" && !isValidDate(arg7))
                {
                    setFocus("TextEndDate");
                    return "Period ending date is not a valid date";
                }

                if (arg6 != "" && arg7 != "")
                {
                    var bd = new Date(arg6);
                    var ed = new Date(arg7);

                    if (bd >= ed)
                    {
                        setFocus("TextEndDate");
                        return "Period ending date must be greater than period beginning date";
                    }
                }

                return "";
            }
        }
    ,   {
            'appendCriteria' : function(label, value) { this.criteria = conjunctionize(this.criteria, label, value); }
        ,   'criteria' : ''
        ,   'clear' : function ()
            {
                document.getElementById("TextProject").value = "";
                document.getElementById("TextContract").value = "";
                setFocus("TextProject");
            }
        ,   'startSearch': function(p)
            {
                searchID++;
                searchType = "fielded";

                var arg1 = document.getElementById("TextProject").value;
                var arg2 = document.getElementById("TextContract").value;
                this.criteria   = '';

                this.appendCriteria('The project number starts with', arg1);
                this.appendCriteria('The contract number contains', arg2);

                BPA.Pisces.Publication.Search.DocumentSearch.SearchByProjectAndContract
                    (
                        arg1
                    ,   arg2
                    ,   ''
                    ,   '+'
                    ,   p
                    ,   onSearchComplete
                    ,   onSearchError
                    ,   { 'pane' : panes[1], 'id' : searchID }
                    );
                return true;
            }
        ,   'validateSearch' : function()
            {
                var arg1 = document.getElementById("TextProject").value;
                var arg2 = document.getElementById("TextContract").value;

                if (arg1 == "" && arg2 == "")
                {
                    setFocus("TextProject");
                    return "You must specify a project number, a contract number, or both";
                }

                if (arg1 != "")
                {
                    var re = /^[0-9]{4}\-[0-9]{3}\-[0-9]{2}$|^[0-9]{9}$|^[0-9]{4}$/;
                    if (!arg1.match(re))
                        return "The project number must be in one of the following formats:\n\nYYYY\nYYYY-###-##\nYYYY######";
                }

                return "";
            }
        }
    ,   {
            'appendCriteria' : function(label, value) { this.criteria = conjunctionize(this.criteria, label, value); }
        ,   'criteria' : ''
        ,   'clear' : function ()
            {
                document.getElementById("TextDocumentID").value = "";
                setFocus("TextDocumentID");
            }
        ,   'startSearch': function(p)
            {
                searchID++;
                searchType = "fielded";

                this.criteria   = '';
                var arg1        = document.getElementById("TextDocumentID").value;
                this.appendCriteria('The Document ID starts with', arg1);
                BPA.Pisces.Publication.Search.DocumentSearch.SearchByDocumentKey
                    (
                        arg1
                    ,   ''
                    ,   '+'
                    ,   p
                    ,   onSearchComplete
                    ,   onSearchError
                    ,   { 'pane' : panes[0], 'id' : searchID }
                    );
            }
        ,   'validateSearch' : function()
            {
                var id = document.getElementById("TextDocumentID").value;
                if (id == "")
                {
                    setFocus("TextDocumentID");
                    return "Document ID must not be blank";
                }
                return "";
            }
        }
    ,   {
            'appendCriteria' : function(label, value) { this.criteria = conjunctionize(this.criteria, label, value); }
        ,   'criteria' : ''
        ,   'clear' : function ()
            {
                document.getElementById("TextFullText").value = "";
                setFocus("TextFullText");
            }
        ,   'startSearch': function(p)
            {
                searchID++;
                searchType = "fulltext";

                this.criteria   = '';
                var arg1        = document.getElementById("TextFullText").value;
                this.appendCriteria('Full text search expression', arg1);

                BPA.Pisces.Publication.Search.DocumentSearch.SearchByDocumentText
                    (
                        arg1
                    ,   p
                    ,   onSearchComplete
                    ,   onSearchError
                    ,   { 'pane' : panes[0], 'id' : searchID }
                    );
            }
        ,   'validateSearch' : function()
            {
                var text = document.getElementById("TextFullText").value;
                if (text == "")
                {
                    setFocus("TextFullText");
                    return "Documents containing text field must not be blank";
                }
                return "";
            }
        }
    ];

function buildSelect(select, options, valueGetter, textGetter)
{
    var count = select.length;

    for (var i = 0; i < count - 1; i++)
        select.remove(1);

    var msie = window.navigator.userAgent.indexOf('MSIE ');

    for (var i = 0; i < options.length; i++)
    {
	    var option      = document.createElement("OPTION");
	    option.value    = valueGetter(options[i]);
	    option.text     = textGetter(options[i]);

		if (msie > 0)
		    select.add(option, i + 1);
	    else
	        select.add(option, null);
    }
}

function clearSearch(index)
{
    panes[index].clear();
}

function conjunctionize(target, label, value)
{
    if (value == null || value == "")
        return target;

    if (target != "")
        target = target + ' <i>and</i><br>';

    return target + label + ': <b>' + value + '</b>';
}

function getSelectedText(id)
{
    var sel = document.getElementById(id);
    if (sel == null)
        return "";

    return sel.options[sel.selectedIndex].text;
}

function getScrollTop()
{
    if (document.documentElement && !document.documentElement.scrollTop)
        // IE6 +4.01 but no scrolling going on
        return 0;
    else if (document.documentElement && document.documentElement.scrollTop)
        // IE6 +4.01 and user has scrolled
        return document.documentElement.scrollTop;
    else if (document.body && document.body.scrollTop)
        // IE5 or DTD 3.2
        return document.body.scrollTop;
    else
        return 0;
}

function getWindowHeight()
{
    var y = 0;

    if (self.innerHeight)   // all browsers except ie
	    y = self.innerHeight;
    else if (document.documentElement && document.documentElement.clientHeight) // ie6 strict mode
	    y = document.documentElement.clientHeight;
    else if (document.body) // other versions of ie
	    y = document.body.clientHeight;

    return y;
}

function getWindowWidth()
{
    var x = 0;

    if (self.innerHeight)
	    x = self.innerWidth;
    else if (document.documentElement && document.documentElement.clientHeight)
	    x = document.documentElement.clientWidth;
    else if (document.body)
	    x = document.body.clientWidth;

    return x;
}

function headerUp(head)         { head.className = 'columnheader'; }
function headerDown(head)       { head.className = 'columnheader pressed'; }
function hideElement(id)        { document.getElementById(id).style.display = "none"; }
function injectHtml(id, html)   { document.getElementById(id).innerHTML = html; }

function inputKeyPressHandler(pane, e)
{
    var key;

     if(window.event)
          key = window.event.keyCode;  // ie
     else
          key = e.which;  //firefox, navigator

    if (key == 13)
    {
        startSearch(pane);
        event.keyCode = 0
    }
}

function isValidDate(d)
{
    var re = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;

    if(!d.match(re))
        return false;

    re.exec(d);

    var xdate = new Date(d);

    if (xdate.getDate() != RegExp.$2)
        return false;

    if (xdate.getMonth() != RegExp.$1 - 1)
        return false;

    if (xdate.getFullYear() != RegExp.$3)
        return false;

    return true;
}

function isValidMonthYear(d)
{
    var re = /^(\d{1,2})\/(\d{4})$/;

    if(!d.match(re))
        return false;

    re.exec(d);

    var xdate = new Date(RegExp.$1 + '/1/' + RegExp.$2);

    if (xdate.getMonth() != RegExp.$1 - 1)
        return false;

    if (xdate.getFullYear() != RegExp.$2)
        return false;

    return true;
}

function isVisible(id)
{
    var element = document.getElementById(id);
    if (!element)
        return false;

    var display = element.style.display;
    if (!display || display == '' || display == 'none')
        return false;

    return true;
}

function jumpToPage(page)
{
    hideElement('detail');

    // if the page already exists in the browser, just render the results
    if (pages[page - 1])
    {
        if (searchType == "fulltext")
            renderResultsFullText(pages[page - 1]);
        else
            renderResultsTable(pages[page - 1]);

        renderPageNavigator(page, pages.length, 5);
        return;
    }

    // otherwise, start another ansynchronous search to pull it down
    document.body.style.cursor = 'wait';
    pane.startSearch(page);
}

function moveElement(id, x, y)
{
    var element = document.getElementById(id);
    if (!element) return;
    element.style.top  = y;
    element.style.left = x;
}

function onOrganizationChange()
{
    var select  = document.getElementById("SelectOrganization");
    var orgid   = select.options[select.selectedIndex].value;

    if (orgid == '')
        orgid = 0;

    BPA.Pisces.Publication.Search.DocumentSearch.GetAuthors
        (
            orgid
        ,   function(result, eventArgs)
            {
                authors     = result;
                var select  = document.getElementById("SelectAuthor")
                buildSelect(select, authors, function(author) { return author.ID; }, function(author) { return author.LastName + ', ' + author.FirstName; });
            }
        ,   function(e)
            {
                var msg = 'This page failed to retrieve the list of available\nauthors for this organization. Please ';
                msg    += 'refresh the page and try again.\n\n';
                msg    += 'Detail: ' + e.get_message();
                alert(msg);
            }
        );
}

// called when the page first loads
function onPageLoad()
{
    BPA.Pisces.Publication.Search.DocumentSearch.GetAuthors
        (
            0
        ,   function(result, eventArgs)
            {
                authors     = result;
                var select  = document.getElementById("SelectAuthor")
                buildSelect(select, authors, function(author) { return author.ID; }, function(author) { return author.LastName + ', ' + author.FirstName; });
            }
        ,   function(e)
            {
                var msg = 'This page failed to retrieve the list of available\nauthors. Please ';
                msg    += 'refresh the page and try again.\n\n';
                msg    += 'Detail: ' + e.get_message();
                alert(msg);
            }
        );

    BPA.Pisces.Publication.Search.DocumentSearch.GetOrganizations
        (
            function(result, eventArgs)
            {
                orgs        = result;
                var select  = document.getElementById("SelectOrganization")
                buildSelect(select, orgs, function(org) { return org.ID; }, function(org) { return org.Name; });
            }
        ,   function(e)
            {
                var msg = 'This page failed to retrieve the list of available\norganizations. Please ';
                msg    += 'refresh the page and try again.\n\n';
                msg    += 'Detail: ' + e.get_message();
                alert(msg);
            }
        );

    BPA.Pisces.Publication.Search.DocumentSearch.GetDocumentTypes
        (
            function(result, eventArgs)
            {
                types       = result;
                var select  = document.getElementById("SelectType")
                buildSelect(select, types, function(type) { return type.ID; }, function(type) { return type.Name; });

                var doctype = qstring('documenttype');

                if (doctype)
                    for (var i = 0; i < select.options.length; i++)
                        if (select.options[i].value == doctype)
                        {
                            select.selectedIndex = i;
                            break;
                        }
            }
        ,   function(e)
            {
                var msg = 'This page failed to retrieve the list of available\npublication types. Please ';
                msg    += 'refresh the page and try again.\n\n';
                msg    += 'Detail: ' + e.get_message();
                alert(msg);
            }
        );
}

function onSearchComplete(result, context, method)
{
    if (isVisible('inputdiv'))
        return;     // an abandoned search just completed...

    // if the searchID returned in the context is different than the current search id
    // then we know that this search was abandoned in favor of another.
    if (searchID != context.id)
        return;

    document.body.style.cursor = '';

    matchCount  = result.MatchCount;
    pageSize    = result.PageSize;

    if (result.MatchCount == 0)
    {
        hideElement("searchdiv");
        showElement("noresultsdiv");
    }
    else
    {
        injectHtml("criteria", pane.criteria);

        if (pages.length == 0)
            pages = new Array(result.PageCount);

        if (result.Page.IsLastPage)
        {
            matchCount = result.Page.EndIndex;

            if (pages.length != result.Page.Number)
                pages = new Array(result.Page.Number);
        }

        pages[result.Page.Number - 1] = result.Page;

        if (method != "SearchByDocumentText")
            renderResultsTable(pages[result.Page.Number - 1]);
        else
            renderResultsFullText(pages[result.Page.Number - 1]);

        renderPageNavigator(result.Page.Number, result.PageCount, 5);

        hideElement("searchdiv");
        showElement("resultsdiv");
    }
}

function onSearchError(e)
{
    hideElement("searchdiv");
    showElement("inputdiv");
    document.body.style.cursor = '';

    var msg = 'This page failed to retrieve the results of the search you\nrequested. Please ';
    msg    += 'refresh the page and try again.\n\n';
    msg    += 'Detail: ' + e.get_message();
    alert(msg);
}

function qstring(name)
{
    name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
    var regex   = new RegExp("[\\?&]"+name+"=([^&#]*)");
    var results = regex.exec(window.location.href);

    if (results == null)
        return "";

    return results[1];
}

function renderPageNavigator(page, pageCount, window_size)
{
    var j       = 0;
    var html    = '';
    var windows = Math.floor(pageCount / window_size);

    if (pageCount % window_size > 0)
        windows++;

    var window  = Math.floor(page / window_size);
    if (page % window_size > 0)
        window++;

    var window_page = page % window_size;

    if (window_page == 0)
        window_page = window_size;

    // windows = the count of groups of pages visible on a single navigator
    // window  = the current window
    // window_page = the offset of the current page within the window

    if (window > 1)
    {
        j = (window - 1) * window_size;
        html += '<a href="javascript:jumpToPage(' + j + ')"><</a> ';
    }

    for (var i = 1; i <= window_size; i++)
    {
        if (window == windows && ((window - 1) * window_size) + i > pageCount)
            break;

        j = (window - 1) * window_size + i;

        if (window_page == i)
            html += '<b>' + j + '</b> ';
        else
            html += '<a href="javascript:jumpToPage(' + j + ')">' + j + '</a> ';
    }

    if (window < windows)
    {
        j = (window * window_size) + 1;
        html += '<a href="javascript:jumpToPage(' + j + ')">></a> ';
    }

    injectHtml("pagenav", html);

    var s = pages[page - 1].StartIndex;
    var e = pages[page - 1].EndIndex;

    if (searchType == "fulltext")
        injectHtml('topmatchcount', "an estimated " + matchCount + " results for:");
    else
        injectHtml('topmatchcount', "" + matchCount + " documents where:");

    injectHtml('matchcount' , s + '-' + e + ' of ' + matchCount);
}

function renderResultsTable(page)
{
    showElement("results")
    hideElement("resultsFullText");

    var tbody   = document.getElementById("resultrows");
    var docs    = page.Summaries;

    while (tbody.rows.length > 0)
        tbody.deleteRow(0);

    for (var i = 0; i < docs.length; i++)
    {
        var tr = tbody.insertRow(tbody.rows.length);

        if (i % 2 == 1)
            tr.style.backgroundColor = "aliceblue";

        var td = tr.insertCell(tr.cells.length);
        td.setAttribute("class", "col1");
        td.innerHTML = docs[i].Key;

        td = tr.insertCell(tr.cells.length);
        td.setAttribute("class", "col2");
        td.innerHTML = '<a href="' + docs[i].URL + '" target="_blank">[' + docs[i].DocumentType + '] ' + docs[i].Title + '</a>';

        td = tr.insertCell(tr.cells.length);
        td.setAttribute("class", "col3");
        td.innerHTML = docs[i].CoversPeriod;

        td = tr.insertCell(tr.cells.length);
        td.setAttribute("class", "col4");
        td.innerHTML = docs[i].ProjectNumber;

        td = tr.insertCell(tr.cells.length);
        td.setAttribute("class", "col5");
        td.innerHTML = docs[i].ContractNumber;

        td = tr.insertCell(tr.cells.length);
        td.setAttribute("class", "col6");
        td.innerHTML = docs[i].UploadDate;

        td = tr.insertCell(tr.cells.length);
        td.setAttribute("class", "col7");
        td.innerHTML = "<a href=\"#\" onclick=\"javascript:showDetail('" + docs[i].Key + "', event);return false;\"><img alt=\"More information...\" src=\"controls/images/moreinfo.gif\" border=\"0\"/></a>";
    }
}

function renderResultsFullText(page)
{
    showElement("resultsFullText");
    hideElement("results")

    var tbody   = document.getElementById("fullTextBody");
    var docs    = page.Summaries;

    while (tbody.rows.length > 0)
        tbody.deleteRow(0);

    for (var i = 0; i < docs.length; i++)
    {
        var tr = tbody.insertRow(tbody.rows.length);
        var td = tr.insertCell(tr.cells.length);

        var html = '<p/><b>[' + docs[i].DocumentType + ']</b> <a href=\"' + docs[i].URL + '" target="_blank">';
        html += "<span class=\"documenttitle\">" + docs[i].Title + "</span></a>";
        html += "<br/><span class=\"documentsnippet\">" + docs[i].Snippet + "</span>";
        html += "<br/><span class=\"documenturl\">" + docs[i].URL + "</span><p/>";

        td.innerHTML = html;
    }
}

function setFocus(id) { document.getElementById(id).focus(); }

function showDetail(key, clickEvent)
{
    var e = (clickEvent) ? clickEvent : ((event) ? event : null);

    var x = 0;
	var y = 0;

    if (e)
    {
        // get the mouse coordinates relative to the document
	    if (e.pageX || e.pageY)
	    {
		    x = e.pageX;
		    y = e.pageY;
	    }
	    else if (e.clientX || e.clientY)
	    {
		    x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		    y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
		}
	}

    injectHtml('detailtitle', 'Properties');
    injectHtml('properties', '<img id="pleasewait" src="controls/images/loading.gif" border="0"/>');

    var details = document.getElementById('detail');
    x -= 410;

    if (y + 235 > getWindowHeight())
        y -= 235;

    moveElement('detail', x, y);
    showElement('detail');

    BPA.Pisces.Publication.Search.DocumentSearch.GetDocumentDetail
        (
            key
        ,   function(result, eventArgs)
            {
                var html = '<p><b><u>Primary Author</u></b><br/>' + result.Author + '</p>';
                html    += '<p><b><u>Author\'s Organization</u></b><br/>' + result.AuthorOrganization + '</p>';

                if (result.SecondaryAuthors != '')
                    html    += '<p><b><u>Other Authors</u></b><br/>' + result.SecondaryAuthors + '</p>';

                html    += '<p><b><u>Description</u></b><br/>' + result.Description + '</p>';
                html    += '<p><b><u>File Size</u></b><br/>' + result.FileSize + ' bytes</p>';

                injectHtml('detailtitle', 'Properties for Document ID ' + result.Key);
                injectHtml('properties', html);
            }
        ,   function(e)
            {
                var msg = 'This popup failed to retrieve the document\ndetails. Please ';
                msg    += 'close the popup and try again.\n\n';
                msg    += 'Detail: ' + e.get_message();
                alert(msg);
            }
        );
}

function showElement(id)    { document.getElementById(id).style.display = "block"; }

// called by anchor tag clicks
function showSearch()
{
    hideElement('detail');
    showElement("inputdiv");
    hideElement("searchdiv");
    hideElement("resultsdiv");
    hideElement("noresultsdiv");
}

// called by search button clicks
function startSearch(panel)
{
    var msg = panes[panel].validateSearch();

    if (msg != "")
    {
        alert(msg);
        return;
    }

    hideElement("inputdiv");
    showElement("searchdiv");

    pages = new Array();
    pane  = panes[panel];
    pane.startSearch(1);
}

