﻿var SuggestedReadings = {

    DcrRegExArrayStr: null,
    EnableDebug: false,
    DcrFilterRegexArray: null,
    UserID: null,
    CategoryDirection: null,
    PopupDirection: null,
    //   WordCountSearchLength:  How 'deep' into the Page should the search be performed.
    //               The larger the number, the longer it could take to process
    //               and find Keywords.
    //               Enter '-1' to search the ENTIRE page    
    WordCountSearchLength: 0,
    //   WordCountThreshold:  The number of times a word has to appear in the Page to be
    //               considered a 'keyword'    
    WordCountThreshold: 0,
    IgnoreWordCount: false,
    ModSearchAry: null,
    WordCountReturnResults: 0,
    Position: null,
    IgnoreWords: new Array('the', 'you', 'and', 'for', 'are', 'this', 'that', 'from', 'said', 'your', 'with', 'not', 'than', 'their'),
    ReadingControl: "$('div[id$=_RelatedContentList]')",
    ReadingList: "$('div[id$=_panelRelatedContentList]')",
    ReadingTable: "$('table[id$=_tblButtonContainer]')",
    ReadingButton: "$('a[id$=_btnRelatedContent]')",
    PopupButton: "$('input[id$=_btnOpenPopup]')",
    ReadingTitle: "$('td[id$=_ReadingTitle]')",

    FindRegExWords: function() {
        var regExWordsArray = new Array();
        var bodyWords = document.getElementsByTagName('body')[0].innerHTML;

        //var str = 'This is <B>a</B> test <b>string</b>.<H1>This is a header</H1> and not a <H3>Header</H3>!';
        var regExArray = this.DcrRegExArrayStr.split(',');
        for (var i = 0; i < regExArray.length; i++) {

            //var re = new RegExp("<b\\b[^>]*>(.*?)</b>", "g");
            // g: global search
            // i: ignore case
            var re = new RegExp(regExArray[i], "gi");
            //var myArray = str.match(re);
            var myArray = bodyWords.match(re);

            if (myArray != null && myArray.length > 0) {
                var theWords = myArray.join(" ");
                regExWordsArray.push(theWords);
            }
            else {
                //Even if no matches are found for this RegEx, create a blank slot
                //in the array.
                regExWordsArray.push("");
            }
        }
        return regExWordsArray;
    },
    RenderContentList: function() {

        // Always show user preference button
        if (eval(this.ReadingButton).length == 0)
            eval(this.ReadingControl).slideDown("fast");
        if (this.Position == "ToolbarPopup")
            $('#ToolbarSeparator').show();
        //The 'DcrFilterRegexArray' var was set on the client side.  Need to make that
        //string a Javascript array.
        var filteringRegexArray = this.DcrFilterRegexArray.split(',');

        // ***** Page Title *****				    
        var theTitle = document.title;

        // ***** Get META Keywords *****
        var allMetaKeywords = this.GetMetaKeywords().join(" ");

        // *** Get Regular Expressions ****    
        var regExWordsArray = this.FindRegExWords();

        // ***** Get Word Count *****
        //Search for Keywords in the <body> of the Page, based
        //on the number of times a single word appears on that page.
        var freqFoundWords = '';
        if (!this.IgnoreWordCount) {
            var arrayFreqWords = this.GetPageBodyKeywords();

            var sl;
            if (this.WordCountReturnResults > arrayFreqWords.length) {
                sl = arrayFreqWords.length;
            }
            else {
                sl = this.WordCountReturnResults;
            }

            //An array of Frequently Found keywords is returned, in Descending order.
            //Only return the Top xx words in a string.
            var count = 0;
            for (var i = 0; i < arrayFreqWords.length; i++) {
                var theWord = arrayFreqWords[i][1].toLowerCase();
                if (theWord.length > 2) {
                    var ignore = SuggestedReadings.IgnoreWords.find(theWord);
                    if (ignore.length == 0) {
                        freqFoundWords += theWord + ' (' + arrayFreqWords[i][0] + ') ';
                        count++;
                        if (count >= sl) break;
                    }
                }
            }
            if (this.EnableDebug) {
                alert('Freq found words: \n' + freqFoundWords);
            }
        }

        //Then, loop thru Xtendable Modules to search
        if (this.ModSearchAry != null && this.ModSearchAry.constructor == Array) {
            for (var i = 0; i < this.ModSearchAry.length; i++) {
                var searchType = this.ModSearchAry[i].ModSearchId;
                DcrAjaxService.ParseAll(searchType,
                    this.UserID,
                    theTitle,
                    allMetaKeywords,
                    freqFoundWords,
                    regExWordsArray,
                    this.EnableDebug,
                    window.location.toString(),
                    this.OnSearchSucceeded,
                    this.OnSearchFailed,
                    searchType);
            }
        }
    },
    //
    // Searches the <body> of the page and returns an array of each Word
    // and the number it occurs.
    //
    //  Array Element Format: '4||theWord'
    //
    GetPageBodyKeywords: function() {

        var bodyWords = document.getElementsByTagName('body')[0].innerHTML;

        var filteringRegexArray = this.DcrFilterRegexArray.split(',');
        //Filter/ignore specific sections from the <body> section i.e. the 'bodyWords'
        //variable above.
        var regex = new RegExp("[\\r|\\n]?", "gi");
        bodyWords = bodyWords.replace(regex, "");

        for (var j = 0; j < filteringRegexArray.length; j++) {
            var regex = new RegExp(filteringRegexArray[j], "gi");
            bodyWords = bodyWords.replace(regex, "");
        }

        var div = document.createElement("div");
        //Bug TFS #4438 - This throws script error on MyAOSPage
        //div.innerHTML = bodyWords;
        var text = document.createTextNode(bodyWords);
        div.appendChild(text);
        //end bug fix

        bodyWords = div.innerText;
        
        //Separate the entire body into 'separate' words
        var mtch = bodyWords.match(/\w+/g);

        var sl;
        if (this.WordCountSearchLength < 0) {
            sl = mtch.length;
        }
        else {
            if (this.WordCountSearchLength > mtch.length) {
                sl = mtch.length;
            }
            else {
                sl = this.WordCountSearchLength;
            }
        }
        //Perform algorithm to find number of words on Page
        var list = this.BuildWordCountList(mtch.slice(0, sl));
        var sortedList = list.sort(sortByCount);

        return sortedList;
    },
    //
    //Looks for the <meta> tag, then the 'Keywords' attribute
    //
    GetMetaKeywords: function() {
        var m = document.getElementsByTagName("META");
        var aryKeywords = new Array();

        for (var i = 0; i < m.length; i++) {
            var metaName = m[i].name;
            if (metaName.toLowerCase() == 'Keywords'.toLowerCase()) {
                aryKeywords.push(m[i].content);
            }
        }
        return aryKeywords;
    },
    //
    //Loops through the provided Content (string) and counts the
    //number of instances of each word, based on certain rules:
    //  1.  No numerals
    //  2.  Ignore 'Commonly Used' words (i.e. 'the', 'in', etc)
    //  3.  Ignore one-letter words.
    //
    //Once a word is been processed, its put into a 'alreadyProcessed' array
    //so its not processed and counted again later
    //
    BuildWordCountList: function(content) {

        var wordCtArray = new Array();
        var alreadyProcessed = new Array();

        //Loop thru each word:
        //    Find # of instances of Word
        //    Save this # and Word to Array ('4&&Word')
        //    Add this Word to the 'alreadyProcessed' array (so its not counted again later)
        for (var i = 0; i < content.length; i++) {
            //Ignore Numeric items and one-letter Words
            if (isNumeric(content[i]) != true && content[i].length > 1) {

                var word = content[i].toLowerCase();
                //Dont count this Word if it was previously counted
                var ap = alreadyProcessed.find(word);
                if (ap.length == 0) {
                    //Find all instances of this particular Word
                    var tmp = content.find(word);
                    //Only save this Word if the number of occurences 
                    //is greater than the Threshold
                    if (tmp.length >= this.WordCountThreshold) {
                        var keywordEntry = new Array(tmp.length, word);
                        wordCtArray.push(keywordEntry);
                    }

                    //Flag this word as one we've already processed, so we dont
                    //accidentally add it agin later, etc.
                    alreadyProcessed.push(word);
                }
            }
        }
        return wordCtArray;
    },
    DisplayControls: function() {
        var btn = eval(this.ReadingButton);
        var con = eval(SuggestedReadings.ReadingControl);
        eval(SuggestedReadings.ReadingTitle).css("display", "block");

        if (btn.length > 0) {
            btn.show(
                function() {
                    var btnLeft = btn.offset();
                    con.css("position", "absolute");
                    con.width(($(window).width() * .6));

                    var btnTop = eval(SuggestedReadings.ReadingTable);
                    if (SuggestedReadings.Position == "UpperRightPopup") {
                        con.css("top", btnTop.offset().top + btnTop.height());
                        btn.unbind("click");
                        btn.click(function() {
                            con.css("left", btnLeft.left - con.width() + btn.width() + 5);
                            eval(SuggestedReadings.ReadingControl).slideDown('fast');
                        });
                    } else {
                        if (con.height() > ($(window).height() - 100)) {
                            con.height($(window).height() - 100);
                            con.css("overflow", "scroll");
                        }
                        con.css("top", -con.height());
                        btn.unbind("click");
                        btn.click(function() {
                            con.css("left", btnLeft.left - con.width() + btn.width() - 20);
                            eval(SuggestedReadings.ReadingControl).slideDown('fast');
                        });
                    }
                }
            );
            $(document).click(function() {
                var c = eval(SuggestedReadings.ReadingControl);
                if (c.height() > 10)
                    c.slideUp('fast');
            });
        } else {
            if (this.Position != "BottomNav")
                con.width("230");
            eval(SuggestedReadings.ReadingControl).slideDown('fast');
        }
    },
    RenderHeaderRow: function(searchType) {
        var hdrText = '';
        var imgIconPath = '';

        //Loop thru the 'modSearchAry' object which 
        //contains all XTModule Search info.
        if (this.ModSearchAry != null && this.ModSearchAry.constructor == Array) {
            for (var i = 0; i < this.ModSearchAry.length; i++) {
                if (searchType == this.ModSearchAry[i].ModSearchId) {
                    hdrText = this.ModSearchAry[i].ModName;
                    imgIconPath = this.ModSearchAry[i].ModIconPath;
                }
            }
        }

        //Includes the Icon Image and Label.
        var hdrCell = document.createElement("td");
        var hdrIconCell = document.createElement("td");

        hdrCell.innerHTML = hdrText;
        hdrCell.setAttribute("width", "99%");
        hdrCell.style.padding = '5px';
        hdrCell.style.whiteSpace = 'nowrap';
        hdrCell.style.textAlign = 'left';
        hdrCell.style.verticalAlign = 'middle';
        hdrCell.style.fontSize = '13px';
        hdrCell.style.fontWeight = 'bold';

        hdrIconCell.innerHTML = '<img src=\'' + imgIconPath + '\' border=\'0\' />';
        hdrIconCell.setAttribute("width", "1%");

        //Create 'Row'    
        var hdrRow = document.createElement("tr");
        hdrRow.appendChild(hdrIconCell);
        hdrRow.appendChild(hdrCell);

        var tblBody = document.createElement("tbody");
        tblBody.appendChild(hdrRow);

        //Create the 'Table'
        var hdrTable = document.createElement("table");
        hdrTable.setAttribute("width", "100%");
        hdrTable.className = "Dcr-ToolbarHeader";
        hdrTable.appendChild(tblBody);
        return hdrTable;
    },
    BuildContentListTable: function(json, searchType) {
        //Only process if the 'json' instance is an Array
        if (json != null && json.constructor == Array && json.length > 0) {
            var div = document.createElement("div");
            div.id = searchType;
            div.style.textAlign = "left";
            //div.style.border = "1px solid gray";
            div.style.borderBottom = "1px solid #666e33";
            div.style.borderLeft = "1px solid #666e33";
            div.style.borderRight = "1px solid #666e33";

            //Create a Row and Cell for the 'Header' of this
            //grouping of search results and add to TableBody.
            div.appendChild(this.RenderHeaderRow(searchType));

            var tbl = document.createElement("table");
            var tblBody = document.createElement("tbody");

            var row1;
            if (this.PopupDirection == 'Horizontal') {
                row1 = document.createElement("tr");
            }

            for (var i = 0; i < json.length; i++) {

                if (this.PopupDirection == 'Vertical') {
                    row1 = document.createElement("tr");
                }

                var url = json[i].U;
                var title = json[i].T;
                var snippet = json[i].S;

                var C1 = document.createElement("td");
                C1.setAttribute("width", (100 / json.length) + "%");
                C1.style.verticalAlign = "top";
                C1.style.borderBottom = "1px solid #e8e8e8";
                C1.className = "Dcr-CategoryListContainer";
                C1.style.textAlign = "left";
                C1.style.padding = '10px';
                //C1.style.border = '1px solid green';
                C1.innerHTML = '<a href=\'' + url + '\'><b>' + title + '</b></a><br/>' + snippet.replace('<br>', '');
                if (this.EnableDebug)
                    C1.innerHTML += " (" + json[i].Weight + ")";
                row1.appendChild(C1);

                if (this.PopupDirection == 'Vertical') {
                    tblBody.appendChild(row1);
                }
            }

            if (this.PopupDirection == 'Horizontal') {
                tblBody.appendChild(row1);
            }

            tbl.appendChild(tblBody);
            div.appendChild(tbl);
            var readingList = eval(this.ReadingList);
            readingList.append(div);

            tbl.setAttribute("width", "100%");
            tbl.cellPadding = 0;
            tbl.cellSpacing = 0;

            if (this.PopupDirection == "Vertical") {
                // Categories side-by-side
                if (this.CategoryDirection == "Horizontal") {
                    div.style.paddingRight = "20px";
                    div.style.styleFloat = "left";
                    readingList.width((readingList.children().length * 220) + "px");
                    var height = 0;
                    $.each(readingList.children(), function(i, n) {
                        height += $(n).height();
                    });

                    for (var i = 0; i < 4; i++) {
                        if (readingList.height() >= height)
                            readingList.width(readingList.width() + 20 + "px");
                    }
                }
            }
            this.DisplayControls();
        }
    },
    //
    // Callback from DcrAjaxService Web Service call for SUCCESSFUL calls.
    //
    OnSearchSucceeded: function(result, searchType) {
        var json = eval(result);
        if (json != null && json.constructor == Array && json.length > 0 && json[0].D && json[0].D.length > 0) {
            var s = "";
            for (var i = 0; i < json[0].D.length; i++)
                s += json[0].D[i].Word + ":" + json[0].D[i].Num + "\n";
            alert(s);
        }
        SuggestedReadings.BuildContentListTable(json, searchType);
    },
    //
    //Callback from DcrAjaxService Web Service call for FAILED calls.
    //
    OnSearchFailed: function(error, searchType) {
        if (SuggestedReadings.EnableDebug) {
            alert('Failed! ' + error.get_message());
            alert(error.get_stackTrace());
        }
    },
    ShowPopup: function() {
        eval(this.PopupButton).click();
        document.cookie = 'UserPreferenceClick=true';
        return false;
    }
};

$(document).ready(function() {
    SuggestedReadings.RenderContentList();
});

//
//Searches for a specfic item within an array.
//  If nothing is found:
//      Return FALSE
//  If found:
//      Return an array of the item(s)
//
//Use the 'length' function on the returned array to find out how many
//instances of the item were found.
//
Array.prototype.find = function(searchStr) {
    var returnArray = [];
    for (i = 0; i < this.length; i++) {
        if (typeof (searchStr) == 'function') {
            if (searchStr.test(this[i])) {
                returnArray.push(i);
            }
        } else {
            if (this[i].toLowerCase() === searchStr.toLowerCase()) {
                returnArray.push(i);
            }
        }
    }
    return returnArray;
}

//
// Sort function for arrays of words and the number of times they
// appear on a Page
//
function sortByCount(a, b) {
    return b[0] - a[0];        
}

//
//Check to see if the string is a Numeral
//
function isNumeric(str) {

    //[0-9]
    var objRegExp = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;
    return objRegExp.test(str);
}


