//params = {
//  inputId : '',
//  resultsId : '',
//  forceSelection : false,
//  preserveInput : true,
//  akaNames : false,
//  roles : false,
//};
RatingCriterionAutoComplete = function(params) {
    this.input = document.getElementById(params.inputId);
    this.results = document.getElementById(params.resultsId);
    this.preserveInput = !params.preserveInput ? false : true;
    this.akaNames = !params.akaNames ? false : true;
    this.roles = !params.roles ? false : true;
    this.ratingCriterionInfoPanel = null;
    this.onCriterionChosen = new YAHOO.util.CustomEvent('RCAC_CriterionChosen', this);
    this.onSearchFailed = new YAHOO.util.CustomEvent('RCAC_SearchFailed', this);
    this.onSearchInitiated = new YAHOO.util.CustomEvent('RCAC_SearchInitiated', this);

    this.dataSource = new YAHOO.widget.DS_XHR(GLOBALS.contextPath + '/ajax/findRatingCriterion', ['results', 'name', 'id', 'description', 'akaNames', 'shareType', 'roles']);
    this.dataSource.responseType = YAHOO.widget.DS_XHR.TYPE_JSON;
    this.dataSource.scriptQueryAppend = "akaNames=" + this.akaNames +
                                        "&roles=" + this.roles;

    this.autoComplete = new YAHOO.widget.AutoComplete(this.input, this.results, this.dataSource);
    this.autoComplete.minQueryLength = 3;
    this.autoComplete.maxResultsDisplayed = 10;
    this.autoComplete.queryDelay = 0.25;
    this.autoComplete.forceSelection = !params.forceSelection ? false : true;
    // this.autoComplete.typeAhead = true;
    this.autoComplete.allowBrowserAutocomplete = false;
    this.autoComplete.useShadow = true;

    this.autoComplete.formatResult = function(resultItems, query) {
        var result = resultItems[0];
        var resultLC = result.toLowerCase();
        var queryLC = query.toLowerCase();
        var n = resultLC.indexOf(queryLC);
        var html;
        if (n == 0) {
            html =
                [ '<div id="ac_result">',
                '<span class="ac_substring">',
                result.substring(0, query.length),
                '</span>',
                result.substring(query.length),
                '</div>'
            ];
            return html.join('');
        }
        else if (n > 0) {
            html =
                [ '<div id="ac_result">',
                result.substring(0, n),
                '<span class="ac_substring">',
                result.substring(n, n + query.length),
                '</span>',
                result.substring(n + query.length),
                '</div>'
            ];
            return html.join('');
        }
        else {
            return result;
        }
    }

    this.showRatingCriterionInfoPanel = function(query, ratingCriterion) {
        if (!this.ratingCriterionInfoPanel) {
            var options = {
                width: '320px',
                visible: false,
                draggable: false,
                close: false,
                constraintoviewport: true,
                underlay: 'shadow',
                context: [this.input, 'tl', 'br'],
                zindex: 100
            };
            this.ratingCriterionInfoPanel = new YAHOO.widget.Panel('ratingCriterionInfoPanel', options);
            this.ratingCriterionInfoPanel.render(document.body);
            this.ratingCriterionInfoPanel.cfg.setProperty('x', this.ratingCriterionInfoPanel.cfg.getProperty('x') + 10, true);
            this.ratingCriterionInfoPanel.cfg.setProperty('y', this.ratingCriterionInfoPanel.cfg.getProperty('y') + 10, true);
            this.ratingCriterionInfoPanel.cfg.setProperty('context', null, true);
            this.ratingCriterionInfoPanel.cfg.refresh();
        }

        var nameLC = ratingCriterion.name.toLowerCase();
        var descriptionLC = ratingCriterion.description.toLowerCase();
        var queryLC = query.toLowerCase();
        var n = nameLC.indexOf(queryLC);
        var html;
        if (n == 0) {
            html =
                [ '<span class="ac_substring">',
                ratingCriterion.name.substring(0, query.length),
                '</span>',
                ratingCriterion.name.substring(query.length)
            ];
            this.ratingCriterionInfoPanel.setHeader(html.join(''));
        }
        else if (n > 0) {
            html =
                [  ratingCriterion.name.substring(0, n),
                '<span class="ac_substring">',
                ratingCriterion.name.substring(n, n + query.length),
                '</span>',
                ratingCriterion.name.substring(n + query.length)
            ];
            this.ratingCriterionInfoPanel.setHeader(html.join(''));
        }
        else {
            this.ratingCriterionInfoPanel.setHeader(ratingCriterion.name);
        }

        n = descriptionLC.indexOf(query.toLowerCase());
        if (n == 0) {
            html =
                [ '<span class="ac_substring">',
                ratingCriterion.description.substring(0, query.length),
                '</span>',
                ratingCriterion.description.substring(query.length)
            ];
            this.ratingCriterionInfoPanel.setBody(html.join(''));
        }
        else if (n > 0) {
            html =
                [ ratingCriterion.description.substring(0, n),
                '<span class="ac_substring">',
                ratingCriterion.description.substring(n, n + query.length),
                '</span>',
                ratingCriterion.description.substring(n + query.length)
            ];
            this.ratingCriterionInfoPanel.setBody(html.join(''));
        }
        else {
            this.ratingCriterionInfoPanel.setBody(ratingCriterion.description);
        }

        html = [];
        if (ratingCriterion.akaNames && ratingCriterion.akaNames.length > 0) {
            html.push('<br />');
            html.push('<span class="akaHeading">Also known as :</span>');
            html.push('<br />');
            html.push('<span class="akaBody">');
            for (var i = 0; i < ratingCriterion.akaNames.length; i++) {
                html.push(ratingCriterion.akaNames[i]);
                html.push('<br />');
            }
            html.push('</span>');
        }

        if (ratingCriterion.roles && ratingCriterion.roles.length > 0) {
            html.push('<br />');
            html.push('<span class="rolesHeading">Belongs to roles :</span>');
            html.push('<br />');
            html.push('<span class="rolesBody">');
            for (i = 0; i < ratingCriterion.roles.length; i++) {
                html.push(ratingCriterion.roles[i].name);
                html.push(' # ');
            }
            // remove the last #
            html.pop();
            html.push('</span>');
        }

        if (html.length > 0) {
            this.ratingCriterionInfoPanel.setFooter(html.join(''));
        }
        else {
            this.ratingCriterionInfoPanel.setFooter('');
        }

        this.ratingCriterionInfoPanel.render(document.body);
        this.ratingCriterionInfoPanel.show();
    }

    this.hideRatingCriterionInfoPanel = function() {
        if (this.ratingCriterionInfoPanel) {
            this.ratingCriterionInfoPanel.hide();
        }
    }

    var ratingCriterionChosenHandler = function(type, args, me) {
        var criterion = {
            name : args[2][0],
            id : args[2][1],
            description : args[2][2],
            akaNames : args[2][3],
            shareType : args[2][4]
        };

        var roles = args[2][5];
        if (roles && roles.length) {
            criterion.roles = roles;
        }
        if (!me.preserveInput) {
            me.input.value = '';
        }
        me.onCriterionChosen.fire(criterion);
    };
    this.autoComplete.itemSelectEvent.subscribe(ratingCriterionChosenHandler, this);

    var containerCollapseHandler = function(type, args, me) {
        me.hideRatingCriterionInfoPanel();
    };
    this.autoComplete.containerCollapseEvent.subscribe(containerCollapseHandler, this);

    var itemMouseOverHandler = function(type, args, me) {
        var criterion = {
            name : args[1]._oResultData[0],
            description : args[1]._oResultData[2],
            akaNames : args[1]._oResultData[3],
            shareType : args[1]._oResultData[4],
            roles : args[1]._oResultData[5]
        };
        me.showRatingCriterionInfoPanel(me.input.value, criterion);
    };
    this.autoComplete.itemMouseOverEvent.subscribe(itemMouseOverHandler, this);

    var itemArrowToHandler = function(type, args, me) {
        var criterion = {
            name : args[1]._oResultData[0],
            description : args[1]._oResultData[2],
            akaNames : args[1]._oResultData[3],
            shareType : args[1]._oResultData[4],
            roles : args[1]._oResultData[5]
        };
        me.showRatingCriterionInfoPanel(me.input.value, criterion);
    };
    this.autoComplete.itemArrowToEvent.subscribe(itemArrowToHandler, this);

    var dataRequestHandler = function (type, args, me) {
        me.onSearchInitiated.fire();
    };
    this.autoComplete.dataRequestEvent.subscribe(dataRequestHandler, this);

    var dataReturnHandler = function(type, args, me) {
        if (args[2].length == 0) {
            args[0]._elTextbox.focus();
            me.onSearchFailed.fire();
        }
    };
    this.autoComplete.dataReturnEvent.subscribe(dataReturnHandler, this);
};
