var sr_siteList;
var fragLists = [];
var prevLnFrag = '';
var prevFnFrag = '';
var keyCount = 0;
var results;
var infoBox;
var siteID;
var lastname;
var firstname;
var fnListDisp;
var lnListDisp;
var fnOnFocus;
var lnOnFocus;

//var jg_ib = new jsGraphics("infoBox");

var queryInProgress = false;

function showStatus(txt, dbg) {
    tdata.value = 'Searching for matches ...\r\n\r\n' + txt;
    if (dbg) {
//        alert(txt);
    }
}        

function dragUpdateInfo(s) {
    infoBox.value = s;
}

function dragBegin (element, x, y) {
    element.style.zIndex="1";
    element.firstChild.innerHTML = '<img src="images/nature/tn_B117leaves2.gif" width="50" height="20">';
    var s = '#' + element.id + ' (begin drag)' + ' x:' + x + ', y:' + y;
    dragUpdateInfo(s);
}

function dragDrag (element, x, y) {
    var s = '#' + element.id + ' (dragging)' + ' x:' + x + ', y:' + y + ',tbScrollTop:'+results.scrollTop;
    dragUpdateInfo(s);
    if (x<-20) {
        element.style.left = '-20px';
    }
    if (x>20) {
        element.style.left = '20px';
    }
}

function dragEnd (element, x, y) {
    element.style.zIndex="0";
    var s = '#' + element.id + ' (end drag)' + ' x:' + x + ', y:' + y;
    dragUpdateInfo(s);
    element.style.left = '0px';
    element.style.top = '0px';
    element.firstChild.innerHTML = '<img src="images/nature/tn_B117leaves1.gif" width="50" height="20">';
}

function fnSort(e1,e2) {
    var kProps = e1[1];
    var a = e1[2];
    var b = e2[2];
    var retval = 0;
    
    var kMax = kProps.length;
    for (var k=0;k<kMax;k++) {
        switch (kProps[k][0]) {
            case 0:                     // key value is boolean, default false-first
                if (a[k] === b[k]) {break;}
                if(a[k]) {
                    retval = 1;
                } else {
                    retval = -1;
                }
                if (kProps[k][1]) {retval *= -1;}
                break;
            case 1:                     // key value is string numeric, default ascending
                var numA = Number (a[k]);
                var numB = Number (b[k]);
                if (numA == numB) {break;}
                if (numA > numB) {
                    retval = 2;
                } else {
                    retval = -2;
                }
                if (kProps[k][1]) {retval *= -1;}
                break;
            case 2:                     // key value is a string or native numeric, default ascending
                var strA = a[k];
                var strB = b[k];
                if (strA == strB) {break;}
                if (strA > strB) {
                    retval = 3;
                } else {
                    retval = -3;
                }
                if (kProps[k][1]) {retval *= -1;}
                break;
            default:
                return 0;
        }
        if (retval!==0) {
            break;
        }
    }
    return retval;
}

function sortNameList(aInput, pInput, fInput) {
    var aTemp = [];
    var sKey;
    
    for (sKey in aInput) {
        if (!isFunction(aInput[sKey])) {aTemp.push([sKey, pInput, aInput[sKey]]);}
    }
    aTemp.sort(fInput);
    var aOutput = [];
    var nMax = aTemp.length;
    for (var nIndex = 0; nIndex < nMax; nIndex++) {
        sKey = aTemp[nIndex][0];
        aOutput[sKey] = aTemp[nIndex][2];
    }
    return aOutput;
}

function defineDataTable() {
    var tblHTML = '<table class="dataTable" cellspacing="0">';
    tblHTML += '<thead><tr>';
    tblHTML += '<th>Last Name</ th>';
    tblHTML += '<th>Given Name(s)</ th>';
    tblHTML += '<th>Born</ th>';
    tblHTML += '<th>Died</ th>';
    tblHTML += '<th>TreeLinks</ th>';
    tblHTML += '<th>Link</ th>';
    tblHTML += '<th>RootsWeb</ th>';
    tblHTML += '<th>Broken?</ th>';
    tblHTML += '</ tr></ thead>';
    tblHTML += '<tbody id="results">';
    return tblHTML;
}

function displayResultsTable(tblHTML) {
    addInnerHTML('searchResults', tblHTML);
    results = $('results');
}

function onLoadHandler() {
    lastname = $('lastname');
    firstname = $('firstname');
    lnListDisp = $('namelist');
    fnListDisp = $('firstNamelist');
    infoBox = $('infoBox');
    tdata = $('tdata');
    
    lastname.value = "";
    firstname.value = "";
    lnListDisp.options.length = 0;
    fnListDisp.options.length = 0;
    tdata.value = "";
    
    var tblHTML = defineDataTable();
    tblHTML += '</ tbody></ table>';
    displayResultsTable(tblHTML);
    
    //drawEllipses();
}

function showSurnames(response) {
    var tooManyLNs = response.tooManyLNs;
    var tooManyFNs = response.tooManyFNs;
    var tooManyResults = response.tooManyResults;
    var lnCnt = response.lnCnt;
    var fnCnt = response.fnCnt;
    var liCnt = response.liCnt;
    var fiCnt = response.fiCnt;
    var errList = response.errList;
    var lnList = response.lnList;
    var fnList = response.fnList;
    var dtlList = response.dtlList;
    var siteList = response.siteList;
    var lnKyList = {};
    var fnKyList = {};
    
    var lnFrag = lastname.value.toLocaleLowerCase();
    var lnFragLen = lnFrag.length;
    var lnLen = lnList.length;
    
    var fnFrag = firstname.value.toLocaleLowerCase();
    var fnFragLen = fnFrag.length;
    var fnLen = fnList.length;
    
    var dtlLen = dtlList.length;
    
    var lnMaxLen = 0;
    var fnMaxLen = 0;
    
    var surNameText, aTxt, i;
    
    var tblHTML = defineDataTable();
    tblHTML += '</ tbody></ table>';
    displayResultsTable(tblHTML);

    if (errList.length>0) {
        aTxt = 'Unable to complete this search\r\n';
        for (i=0; i<errList.length; i++) {
            aTxt += '\r\n'+errList[i];
        }
        tdata.value = aTxt;
        return;
    }
    else if (tooManyResults) {
        var rsLnFrag = response.lnFrag;
        var rsFnFrag = response.fnFrag;
        var reQuery = true;
        aTxt = 'Too many possible matches';
        if (lnCnt>0) {
            aTxt += '\r\n  '+lnCnt+' last names';
            if (liCnt>0) {
                aTxt += ' ('+liCnt+' individuals)';
            }
            aTxt += " match '"+rsLnFrag+"'";
        }
        if (fnCnt>0) {
            aTxt += '\r\n  '+fnCnt+' first names';
            if (fiCnt>0) {
                aTxt += ' ('+fiCnt+' individuals)';
            }
            aTxt += " match '"+rsFnFrag+"'";
        }
        tdata.value = aTxt;
        return;
    }
    
    var searchName, fVal, kVal, kVals, re, m;
    var mKey;
    
showStatus('counting last name word matches',true);
    lnListDisp.options.length = 0;
    
    var lMatches = [];
    for (i=0;lnLen>i;i++)
    {
        searchName = lnList[i].ls;
        fVal = lnFragLen;
        if (fVal>0 ) {
            fVal = searchName.indexOf(lnFrag);
        }
        kVal = lnList[i].rw;
        kVals = [];
        if (fVal>=0) {
            kVals[0] = true;
            if (dtlLen < 1) {
                kVals[1] = lnList[i].rc;
            }
            else {
                kVals[1] = 0;
            }
            if (lnFragLen>0) {
                re = new RegExp('(^|[^\\w\\.\\-])([\\w\\.\\-]*'+lnFrag+'[\\w\\.\\-]*)([^\\w\\.\\-]|$)');
                m = re.exec(searchName);
                if (m !== null) {
                    mKey = m[2];
                }
            } else {
                mKey = searchName;
            }
        }
        else {
            kVals[0] = false;
            kVals[1] = 0;
            mKey = '';
        }
        kVals[2] = i;
        kVals[3] = mKey;
        lnKyList[kVal] = kVals;
        if (lMatches.indexOf(mKey)<0) {
            lMatches.push(mKey);
        }
    }
showStatus('sorting last name word matches',true);
    lMatches.sort();
    
showStatus('counting first name word matches',true);
    fnListDisp.options.length = 0;
    
    var fMatches = [];
    for (i=0;fnLen>i;i++)
    {
        searchName = fnList[i].fs;
        fVal = fnFragLen;
        if (fVal>0 ) {
            fVal = searchName.indexOf(fnFrag);
        }
        kVal = fnList[i].rw;
        kVals = [];
        if (fVal>=0) {
            kVals[0] = true;
            if (dtlLen < 1) {
                kVals[1] = fnList[i].rc;
            }
            else {
                kVals[1] = 0;
            }
            if (fnFragLen>0) {
                re = new RegExp('(^|[^\\w\\.\\-])([\\w\\.\\-]*'+fnFrag+'[\\w\\.\\-]*)([^\\w\\.\\-]|$)');
                m = re.exec(searchName);
                if (m !== null) {
                    mKey = m[2];
                }
            } else {
                mKey = searchName;
            }
        }
        else {
            kVals[0] = false;
            kVals[1] = 0;
            mKey = '';
        }
        kVals[2] = i;
        kVals[3] = mKey;
        fnKyList[kVal] = kVals;
        if (fMatches.indexOf(mKey)<0) {
            fMatches.push(mKey);
        }
    }
showStatus('sorting first name word matches',true);
    fMatches.sort();

    var lKhits = {};
    var fKhits = {};
    var dHits = [];
    
    lMatches.each( function(item, index){
        var hVals = [];
        hVals[0] = true;
        hVals[1] = 0;
        hVals[2] = index;
        lKhits[item]=hVals;
    });
    fMatches.each( function(item, index){
        var hVals = [];
        hVals[0] = true;
        hVals[1] = 0;
        hVals[2] = index;
        fKhits[item]=hVals;
    });
    
showStatus('filtering detail matches',true);
    var fKey, lKey;
    for (i=0;dtlLen>i;i++) {
        lKey = dtlList[i].lr;
        fKey = dtlList[i].fr;
        if ((lnKyList[lKey][0]) && (fnKyList[fKey][0])) {
            lnKyList[lKey][1]++;
            lKhits[lnKyList[lKey][3]][1]++;
            
            fnKyList[fKey][1]++;
            fKhits[fnKyList[fKey][3]][1]++;
            
            dHits.push([lKhits[lnKyList[lKey][3]][2],fKhits[fnKyList[fKey][3]][2],dtlList[i].by,dtlList[i].dy,i]);
        }
    }
    
showStatus('sorting last name word matches',true);
    var kProps = [];
    kProps.push([0,1]); // 1st key is boolean, true-first
    kProps.push([1,1]); // 2nd key is numeric, descending
    kProps.push([2,0]); // 3rd key is string, ascending
    lKhits = sortNameList(lKhits, kProps, fnSort);
    
showStatus('sorting first name word matches',true);
    kProps = [];
    kProps.push([0,1]); // 1st key is boolean, true-first
    kProps.push([1,1]); // 2nd key is numeric, descending
    kProps.push([2,0]); // 3rd key is string, ascending
    fKhits = sortNameList(fKhits, kProps, fnSort);
    
showStatus('sorting detail matches',true);
    kProps = [];
    kProps.push([2,0]); // 1st key is numeric, ascending
    kProps.push([2,0]); // 2nd key is numeric, ascending
    kProps.push([1,0]); // 3rd key is string numeric, ascending
    kProps.push([1,0]); // 3rd key is string numeric, ascending
    kProps.push([2,0]); // 3rd key is numeric, ascending
    dHits = sortNameList(dHits, kProps, fnSort);
    
showStatus('displaying list of last name matches',true);
    var lastName, lastNameText;
    var j = 0;
    for (kVal in lKhits) {
        if (!isFunction(lKhits[kVal])) {
            if (lKhits[kVal][1]>0) {
                lastName = kVal;
                if (lastName.length>lnMaxLen) {
                    lnMaxLen = lastName.length;
                }
                lastNameText = "("+lKhits[kVal][1]+") "+lastName;
                lnListDisp.options[j] = new Option(lastNameText,lastName);
                j++;
            }
        }
    }
    
showStatus('displaying list of first name matches',true);
    var firstName, firstNameText;
    j = 0;
    for (kVal in fKhits) {
        if (!isFunction(fKhits[kVal])) {
            if (fKhits[kVal][1]>0) {
                firstName = kVal;
                if (firstName.length>fnMaxLen) {
                    fnMaxLen = firstName.length;
                }
                firstNameText = "("+fKhits[kVal][1]+") "+firstName;
                fnListDisp.options[j] = new Option(firstNameText,firstName);
                j++;
            }
        }
    }
    
showStatus('building list of detail matches',true);
    tblHTML = defineDataTable();
    var nameTxt = '';
    var dragableIDs = [];
    if (dtlLen>0) {
        nameTxt = 'Matched Individuals:';
        var noMatches = true;
        var dtlVals;
        for (kVal in dHits) {
            if (!isFunction(dHits[kVal])) {
                dtlVals = dHits[kVal];
                i = dtlVals[4];
                lKey = dtlList[i].lr;
                fKey = dtlList[i].fr;
                if ((lnKyList[lKey][1]>0) && (fnKyList[fKey][1]>0)) {
                    noMatches = false;
                    var bDisp = dtlList[i].by;
                    var bRW = bDisp;
                    if (bDisp==0) {
                        bDisp = '&nbsp;';
                        bRW = '';
                    }
                    var dDisp = dtlList[i].dy;
                    var dRW = dDisp;
                    if (dDisp==0) {
                        dDisp = '&nbsp;';
                        dRW = '';
                    }
                    var lnDisp = lnList[lnKyList[lKey][2]].ln;
                    if (lnDisp.length>30) {
                        lnDisp = left(lnDisp,26)+' ...';
                    }
                    var fnDisp = fnList[fnKyList[fKey][2]].fn;
                    if (fnDisp.length>30) {
                        fnDisp = left(fnDisp,26)+' ...';
                    }
                    var treeLinkID = 'treelink'+i;
                    dragableIDs.push(treeLinkID);
                    var sn = siteList[dtlList[i].sr].sn;
                    var st = siteList[dtlList[i].sr].st;
                    var su = siteList[dtlList[i].sr].su;
                    tblHTML += '<tr style="height:8px;">'
                     + '<td>'+lnDisp+'</ td>'
                     + '<td>'+fnDisp+'</ td>'
                     + '<td>'+bDisp+'</ td>'
                     + '<td>'+dDisp+'</ td>'
                     + '<td align="center"><div id="'+treeLinkID + '"'
                     + ' style="position: relative; z-index: 0;">'
                     + '<a><img style="position: relative; z-index: 0;"'
                     + ' src="images/nature/tn_B117leaves1.gif" width="50" height="20"></a></div></td>'
                     + '<td><a href="'+su;
                    switch (sn) {
                        case '0':
                            tblHTML += '"';
                            break;
                        case '4':
                            tblHTML += '\/individual.php?ged=ancestors.ged&pid='+dtlList[i].rf+'"';
                            break;
                        default:
                            tblHTML += '\/'+dtlList[i].rf+'"';
                    }
                    tblHTML += ' target="dtl'+i+'" onclick="link_popup(this,\'location=0, toolbar=1, statusbar=1, menubar=0, scrollbars=1, width=800, height=600\');return false;">'
                     + st+'</ a></ td>';
                    if (bRW==='' && dRW==='') {
                        tblHTML += '<td>&nbsp;</ td>';
                    } else {
                        var lSearch = lMatches[dtlVals[0]];
                        var fSearch = fMatches[dtlVals[1]];
                        tblHTML += '<td align="center"><a href="'
                         + 'http://wc.rootsweb.ancestry.com/cgi-bin/igm.cgi?op=Search&includedb=&lang=en&ti='
                         + '&surname='+lSearch+'&stype=Exact'
                         + '&given='+fSearch+'&bplace='
                         + '&byear='+bRW+'&brange=1&dplace='
                         + '&dyear='+dRW+'&drange=1&mplace='
                         + '&myear=&mrange=0&father=&mother=&spouse=&skipdb=&period=All&submit.x=Search'
                         + ' target="rw" onclick="link_popup(this,\'location=0, toolbar=1, statusbar=1, menubar=0, scrollbars=1, width=800, height=600\');return false;">'
                         + '<img src="images/search.gif" width="15" height="15"></ a></ td>';
                    }
                    tblHTML += '<td align="center"> <a onclick="javascript:showRefreshWin('+sn+') ">'
                     + '<img src="images/broken.gif" width="15" height="15"></a></ td>'
                     + '</ tr>';
                }
            }
        }
        if (noMatches) {
            nameTxt = 'No Matches:';
        }
        tblHTML += '</ tbody></ table>';
        var dCnt = dHits.length;
        var dTxt = 'displaying list of detail matches';
        if (dCnt>500) {
            dTxt += '\r\n(This may take a while ...)';
        }
        showStatus(dTxt,true);
        displayResultsTable(tblHTML);
        
        dragableIDs.each( function(item, index){
            var drgble = $(item);
            DragHandler.attach(drgble);
            drgble.drag = dragDrag;
            drgble.dragBegin = dragBegin;
            drgble.dragEnd = dragEnd;
        });
        
        tdata.value = nameTxt;
    }
}

function showRefreshWin(site_ID) {
    if (site_ID===undefined) {
        site_ID=siteID;
    }
    var queryArgs='GMaction=siteRefresh&siteID='+site_ID;
    var wProps='menubar=0,scrollbars=1,height=800,width=750';
    var refreshWin = raw_popup('Leaves_SiteRefresh.php?'+queryArgs,'refreshSite'+site_ID,wProps);
}

function nameListResponse(request){
    var response = request.responseText.evalJSON();
    var lnFrag = response.lnFrag;
    var fnFrag = response.fnFrag;
    
    var fragKey = '~'+lnFrag+'~'+fnFrag+'~';
    
    fragLists[fragKey][1] = response;
    showSurnames(response);
    getNameLists(false,keyCount);
}

function isKeyValid(lnFrag, lnKyLen, fnFrag, fnKyLen) {
    var lnKy = '';
    var fnKy = '';
    
    if (lnKyLen>0) {
        lnKy = left(lnFrag, lnKyLen);
    }
    if (fnKyLen>0) {
        fnKy = left(fnFrag, fnKyLen);
    }
    var fragKey = '~'+lnKy+'~'+fnKy+'~';
    if (!(fragLists[fragKey] === undefined)) {
        var nameList = fragLists[fragKey][1];
        if (nameList.noMatch || nameList.dtlList.length>0) {
            return nameList;
        }
    }
    
    return false;
}

function getNameLists(initialCall, kyCnt) {
    if (kyCnt<keyCount) {
        return;
    }
    
    var lnFrag, fnFrag;
    
    if (initialCall) {
        prevLnFrag = '';
        prevFnFrag = '';
        
        lnFrag = lastname.value;
        fnFrag = firstname.value;
        
        if (fnFrag == fnOnFocus && lnFrag == lnOnFocus) {
            return;
        }
        fnOnFocus = fnFrag;
        lnOnFocus = lnFrag;
    }
    
    queryInProgress = true;
    while (queryInProgress) {
        lnFrag = lastname.value;
        fnFrag = firstname.value;
        
        if ((lnFrag == prevLnFrag) && (fnFrag == prevFnFrag)) {
            break;
        }
        
        prevLnFrag = lnFrag;
        prevFnFrag = fnFrag;
        
        var lnFragLen = lnFrag.length;
        var fnFragLen = fnFrag.length;
        
        var tblHTML = defineDataTable();
        tblHTML += '</ tbody></ table>';
        displayResultsTable(tblHTML);
        
        fnListDisp.options.length = 0;
        lnListDisp.options.length = 0;
        
        if (lnFragLen === 0 && fnFragLen === 0) {
            tdata.value = '';
            break;
        }
        
        showStatus('');
        
        var fnIsLonger = false;
        var len1, len2, len3;
        if (fnFragLen>lnFragLen) {
            fnIsLonger = true;
            len1 = fnFragLen;
            len2 = lnFragLen;
        }
        else {
            len1 = lnFragLen;
            len2 = fnFragLen;
        }
        
        var nameList = false;
        var needValidKey = true;
        
        while (len1>0 && needValidKey) {
            len3 = len2;
            while (len3 >=0 && needValidKey) {
                if (fnIsLonger) {
                    nameList = isKeyValid(lnFrag, len3, fnFrag, len1);
                    if(!(nameList===false)) {
                        needValidKey = false;
                        break;
                    }
                }
                else {
                    nameList = isKeyValid(lnFrag, len1, fnFrag, len3);
                    if(!(nameList===false)) {
                        needValidKey = false;
                        break;
                    }
                }
                len3--;
            }
            if (needValidKey) {
                len1--;
            }
        }
        
        if (!(nameList===false)) {
            showSurnames(nameList);
            continue;
        }
        
        var fragKey = '~'+lnFrag+'~'+fnFrag+'~';
        
        if (fragLists[fragKey] === undefined) {
            var newFragItem = [fragKey,[]];
            fragLists[fragKey] = newFragItem;
        }
        else if (fragLists[fragKey][0]==fragKey)
        {
            nameList = fragLists[fragKey][1];
            showSurnames(nameList);
            continue;
        }
        else {
            alert('Unexpected search error - please try again!');
            break;
        }
        
        fnListDisp.options.length = 0;
        lnListDisp.options.length=0;
    
        var parms = 'GMaction=getMatchResults&GMlnFrag='+lnFrag+'&GMfnFrag='+fnFrag+'&GMlnForce=NO&GMfnForce=NO';
        initiateAjaxPost(parms,nameListResponse);
        return;
    }
    queryInProgress = false;
}

function getFirstnameList(obj){
    if (queryInProgress) {
        return;
    }
    
    keyCount++;
    setTimeout("getNameLists(true, " + keyCount + ")", 500);
}

function getSurnameList(obj){
    if (queryInProgress) {
        return;
    }
    
    keyCount++;
    setTimeout("getNameLists(true, " + keyCount + ")", 500);
}

function nameChosen(obj){
    //return;
    //
    //var siteID = $('siteid').value;
    //var snListID = $('snlistid').value;
    //var iChosen = obj.selectedIndex;
    //var surName = obj.options[iChosen].value;
    //siteFragLists = fragLists[siteID];
    //flLen = siteFragLists.length;
    //$('surName').value = surName;
    //$('infoBox').value = 'surNameID = '+surName;
    //$("lastname").value = surName;
    //$("firstname").focus();
}

function firstNameChosen(obj){
    //return;
    //
    //var siteID = document.getElementById('siteid').value;
    //var snListID = document.getElementById('snlistid').value;
    //var iChosen = obj.selectedIndex;
    //var surName = $('surName').value;
    //siteFragLists = fragLists[siteID];
    //flLen = siteFragLists.length;
    //$('surName').value = surName;
    //$('infoBox').value = 'surNameID = '+surName;
    //document.getElementById("lastname").value = surName;
    //document.getElementById("firstname").focus();
}

function updateStatus(text){
    //jg_ib.clear();
    //jg_ib.setColor("blue");
    //jg_ib.setFont("verdana","9px",Font.PLAIN);
    //jg_ib.drawStringRect(text,0,0,500,"center");
    //jg_ib.paint();
}

function myDrawFunction(canvas){
//var jg = new jsGraphics(canvas);
//  jg.setColor("#ff0000"); // red
//  jg.drawEllipse(0,0,50,30); // co-ordinates related to "myCanvas"
//  jg.setColor("blue");
//  jg.setFont("verdana","9px",Font.PLAIN);
//  jg.drawStringRect(canvas,0,6,50,"center");
//  jg.paint();
}

function drawEllipses() {
    //myDrawFunction("dragable_1");
    //myDrawFunction("dragable_2");
    //myDrawFunction("dragable_3");
}

