/**
 * Supports FKey & FKeySet
 * @extends LoginPanelAgent
 */
function LKTableAgent(id) {

        this.init(id);
        this.width = -1;

        this.update = AgentPCB.update;
        this.onLogin = AgentPCB.onLogin

        // set by openPanel
        this.tablePSId = null;
        this.maxTuples = null;
        this.xeReqSpec = null;
        this.distinct = null; // used by Dictionary to eliminate duplicate typical values
        this.sortFields = []; // array of PSIds

    this.openPanel = function(fieldLabel) {

        var xeCommand = (this.recId) ? this.xeGetFieldValue() : this.xeGetModGUIData();
                var eWidgetResult = this.eWidgetResult(xeCommand);
        var eGUI = eWidgetResult.getElementsByTagName('ModGUIData')[0].childNodes[0];

                if (eGUI.tagName=='LoginModGUIData') {
                        this.width = 320;
                        this.initLoginPanel(eGUI);
                        this.openLoginPanel();
                }
        else { // LKTableModGUIData
                this.width = 420;
                var guiLabels = this.getMap(eGUI.getElementsByTagName('GUILabels')[0]);
                        var colorIconDir = eGUI.getAttribute('colorIconDir');
                        var sigIndices = eGUI.getAttribute('significantIndices').split(' ');
                        var sigSep = eGUI.getAttribute('significantSeparator');
                        var newRecordHref = eGUI.getAttribute('newRecordHref');
                        this.tablePSId = eGUI.getAttribute('tablePSId');

                        var eReqSpec = eGUI.getElementsByTagName('ReqSpec')[0];
                        this.xeReqSpec = XMLTools.convertToXE(eReqSpec);
                        this.maxTuples = parseInt(this.xeReqSpec.getAttribute('length'),10);

                        var tableFields = XMLTools.getChildElements(eGUI,'FormatValue');

                        var eResultSet = eGUI.getElementsByTagName('ResultSet')[0];
                        var pageCount = parseInt(((eResultSet.getAttribute('count')-1)/this.maxTuples)+1, 10);
                        var eTuples = XMLTools.getChildElements(eResultSet);
                        var resultSet = new ResultSetObject('',1,pageCount,eTuples);

                        var isListView = (Cookies.get(this.getCookieId())!='table');

                this.panel = new LKTablePanel(this.id, fieldLabel, guiLabels, colorIconDir, isListView,
                        tableFields, sigIndices, sigSep, resultSet, newRecordHref);
                        this.displayPanel();
                        this.setPanelWidth();
                        this.setDivTop();
                        this.panel.setFocus();
                        this.panel.initRowHighlighter()}}

        this.toggleViewType = function() { // cmd : 'list' | 'table'
                this.panel.isListView = !this.panel.isListView;
                this.displayPanel();
                this.setPanelWidth();
                this.panel.setFocus('vtBut');
                this.panel.initRowHighlighter();
                // update cookie
                var cookieValue = (this.panel.isListView) ? 'list' : 'table';
                Cookies.set(this.getCookieId(),cookieValue)}

        /**
         * this.tablePSId must be set first!!!
         */
        this.getCookieId = function() {
                return 'table_'+this.tablePSId+'.typicalViewType'}

        /**
         * this.displayPanel() must be called first
         */
        this.setPanelWidth = function() {
                this.width = (this.panel.isListView) ? 420 : parseInt(d.body.offsetWidth*0.8,10);
                this.getDiv().style.width = this.width}

        /**
         * @return {ResultSetObject}
         */
        this.getResultSet = function(pattern,pageIndex) {

                if (!pattern) pattern = '';
        if (!pageIndex) pageIndex = 1;

                // update xeReqSpec
                this.xeReqSpec.setAttribute('start',((pageIndex-1)*this.maxTuples) + 1);
                var xeQuickFilter = this.xeReqSpec.getChild('QuickFilter');
                if (!xeQuickFilter) xeQuickFilter = new XMLElement('QuickFilter',this.xeReqSpec);
                xeQuickFilter.setAttribute('expr',pattern);

        // create data query XE
        var xeDataQuery = new XMLElement('DataQuery');
        xeDataQuery.setAttribute('count','true');
        xeDataQuery.setAttribute('format','formattedValues');
        var xeRequest = new XMLElement('Request',xeDataQuery);
        xeRequest.setAttribute('psid',this.tablePSId);
        xeRequest.setAttribute('target','table');
        xeRequest.appendChild(this.xeReqSpec);

        // send request
        var eDataResult = ProgramShop.getResultElement(xeDataQuery,this.space,this.DEBUG);

            // get resultSet vars
        var eResultSet = eDataResult.getElementsByTagName('ResultSet')[0];
            var pageCount = parseInt(((eResultSet.getAttribute('count')-1)/this.maxTuples)+1, 10);
        var pageIndex = (pageCount==0) ? 0 : pageIndex;
        var eTuples = XMLTools.getChildElements(eResultSet);

        return new ResultSetObject(pattern,pageIndex,pageCount,eTuples)}

        this.applyPattern = function() {
                this.panel.setResultSet(this.getResultSet(this.panel.getPattern()));
                this.displayPanel();
                this.panel.setFocus()}

        this.gotoPrevPage = function() {
                this.gotoPage(this.panel.pageIndex-1,'back')}

        this.gotoNextPage = function() {
                this.gotoPage(this.panel.pageIndex+1,'next')}

        this.gotoPage = function(page,oFocus) {
                if (!page) page = $('goto_'+this.id).value;
        page = parseInt(page,10);
        if (isNaN(page) || page<1) page = 1;
        else if (page>this.panel.pageCount) page = this.panel.pageCount;
        this.panel.setResultSet(this.getResultSet(this.panel.getPattern(),page));
        this.displayPanel();
        if (!oFocus) oFocus = 'goto';
                this.panel.setFocus(oFocus)}

        this.setRow = function(tr) {
                this.panel.setRow(tr)}

        this.highlightRow = function() {
                if (this.panel) this.panel.listener_highlight();}

        this.select = function(recId) {
                var xmlValue = '<NullValue/>';
                if (recId && recId!='') switch (this.fieldType) {
                        case 'FKey' : xmlValue = '<FKey recId="'+recId+'"/>'; break;
                        case 'FKeySet' :
                                if (this.recId || this.mmrId) {
                                        Manager.getAgent('link_'+this.fieldRef).addFKey(recId);
                                        this.closePanel();
                                        return}
                                else xmlValue = '<FKey recId="'+recId+'"/>'; break;}
                this.submitValue(xmlValue,false)}

        this.deleteItem = function() {
                this.submitValue('<NullValue/>')}

        this.toString = function() {
                return 'LKTableAgent: {id: ' + this.id + '}'}
}

LKTableAgent.prototype = new LoginPanelAgent();


/**
 * @constructor
 * @param {Array} eTuples TupleObject array
 */
function ResultSetObject(pattern,pageIndex,pageCount,eTuples) {
        this.pattern = pattern;
        this.pageIndex = pageIndex;
        this.pageCount = pageCount;
        this.tuples = [];
        for (var i=0; i<eTuples.length; i++) {
                this.tuples[i] = new TupleObject(eTuples[i])}}


/**
 * @constructor
 * @param {Element} eTuple Tuple element
 */
function TupleObject(eTuple) {
        this.id = eTuple.getAttribute('id');
        this.values = [];
        this.str = '';
        var eFormatValues = eTuple.getElementsByTagName('FormatValue');
        for (var i=0; i<eFormatValues.length; i++) {
                var str = (eFormatValues[i].firstChild) ? eFormatValues[i].firstChild.data : '';
                this.values[i] = str;
                this.str += str + ' '}
        this.toString = function() {
                return this.str;
        }
}


/**
 * @param {Array<Element<FormatValue>>} Ordered array of table field labels.
 * @param {Array<Integer>} sigIndices Indices of significant values, in given order.
 * @param {String} sigSep String to separate significant values.
 */
function LKTablePanel(agentId,fieldLabel,guiLabels,colorIconDir,isListView,tableFields,sigIndices,sigSep,resultSet,newRecordHref) {

        this.agentId = agentId;
        this.guiLabels = guiLabels;
        this.fieldLabel = fieldLabel;
        this.colorIconDir = colorIconDir;
        this.isListView = isListView;
        this.tableFields = tableFields;
        this.sigIndices = sigIndices;
        this.sigSep = sigSep;
        this.newRecordHref = newRecordHref;

    this.setResultSet = function(resultSet) {
            this.pageIndex = resultSet.pageIndex;
            this.pageCount = resultSet.pageCount;
            this.tuples = resultSet.tuples;
            this.pattern = (resultSet.pattern) ? resultSet.pattern : '';
        }
        this.setResultSet(resultSet);

        this.getPattern = function() {
            return $('dicFilter_'+this.agentId).value}

    /**
     * @param {String} oRef "back" | "next" | "goto" | "vtBut" | undefined
     */
        this.setFocus = function(oRef) {
                var id = this.agentId;
                var obj = (oRef) ? $(oRef+'_'+id) : null;
                if (!obj) {
                        if (oRef=='back') obj = $('next_'+id);
                        else if (oRef=='next') obj = $('back_'+id);}
                if (!obj) obj = $('dicFilter_'+id);
                if (!obj) obj = $('close_'+id);
                if (obj) obj.focus()}

        this.highlightedRow = null;
        this.rowToHighlight = null;

        this.initRowHighlighter = function() {
                this.listener_highlight()}

        this.listener_highlight = function() {
                if (this.isListView) return;
                if (this.highlightedRow!=this.rowToHighlight) {
                        if (this.highlightedRow!=null)
                                this.highlightedRow.className = this.highlightedRow.className.split('_')[0];
                        if (this.rowToHighlight!=null)
                                this.rowToHighlight.className += '_mouseOver';
                        this.highlightedRow = this.rowToHighlight}
                setTimeout("Manager.getAgentWithId(\'"+this.agentId+"\').highlightRow()",50)}

        this.setRow = function(tr) { // tr is a TR element, called by onMouseOver event
                this.rowToHighlight = tr}

        this.toHTML = function() {
                var agent = "Manager.getAgentWithId(\'"+this.agentId+"\')";

                var vtButName = (this.isListView) ? 'bt_allFields.gif' :  'bt_sigFields.gif';
                var vtButAlt = (this.isListView) ? this.guiLabels.showAllValues :  this.guiLabels.showSignificantValues;

                var html = '<table class="wide ptable">'
                + '<tr>'
                + '<td class="ptitbar" onMouseDown="DragAndDrop.start(this,event); return false">'
                        + '<table class="wide" summary="' + this.guiLabels.titleBar + '">'
                        + '<tr>'
                        + '<td>'+this.fieldLabel + '</td>'
                        + '<td align="right" nowrap valign="top">';

                        // new record link
                        if (this.newRecordHref) {
                                var fieldRef = this.agentId.replace(/^[^_]+_/,'');
                                html += '<a tabIndex="1" id="popup_' + fieldRef+'" onClick="Manager.openPopup(this,\''
                                + this.newRecordHref + '\'); return false" href="Manager.openPopup" class="new"><img src="'
                                + this.colorIconDir + 'bt_newDoc.gif" class="bt11 m04">' + this.guiLabels.newRecord + '</a>'}

                        html += '<input type="image" onClick="'+agent+'.toggleViewType(); return false" '
                        + 'src="'+this.colorIconDir+vtButName+'" class="bt11 m04" '
                        + 'alt="'+vtButAlt+'" tabIndex="1" id="vtBut_'+this.agentId+'">'
                        + '<input type="image" onClick="'+agent+'.closePanel(); return false" '
                        + 'src="'+this.colorIconDir+'bt_close_11.gif" class="bt11" '
                        + 'alt="'+this.guiLabels.close+'" tabIndex="1" id="close_'+this.agentId+'"></td>'
                        + '</tr>'
                        + '</table>'
                + '</td>'
                + '</tr>';
                if (this.pageCount>0 || this.pattern!='') {
                        html += '<tr>'
                        + '<td>'
                                + '<div class="dicNav">'
                                + '<table class="wide">'
                                + '<tr>'
                                + '<td nowrap>'+this.guiLabels.containing
                                + '&nbsp;<input type="text" id="dicFilter_'+this.agentId+'" '
                                + 'onKeyPress="if (event.keyCode==13) {'+agent+'.applyPattern(); return false}" size="12" '
                                + 'value="'+this.pattern+'"' + ' tabIndex="2">&nbsp;'
                                + '<input type="image" src="/rsrc/img/bt_right.gif" class="btNav" tabIndex="3" '
                                + 'onClick="'+agent+'.applyPattern(); return false" alt="'+this.guiLabels.filter+'">'
                                + '</td>';
                                if (this.pageCount>0) {
                                        html += '<td nowrap align="center">';
                                        if (this.pageIndex>1) html += '<input type="image" src="/rsrc/img/bt_left.gif" '
                                        + 'class="btNav" onClick="'+agent+'.gotoPrevPage(); return false" '
                                        + 'alt="'+this.guiLabels.back+'" id="back_'+this.agentId+'" tabIndex="4">&nbsp;';
                                        html += this.guiLabels.page+'&nbsp;'+this.pageIndex+'&nbsp;'
                                        + this.guiLabels.of+'&nbsp;'+this.pageCount;
                                        if (this.pageIndex<this.pageCount) html += '&nbsp;<input type="image" '
                                        + 'src="/rsrc/img/bt_right.gif" class="btNav" '
                                        + 'onClick="'+agent+'.gotoNextPage(); return false" '
                                        + 'alt="'+this.guiLabels.next+'" id="next_'+this.agentId+'" tabIndex="5">';
                                        html += '</td>'}
                                if (this.pageCount>2) html += '<td nowrap align="right">'+this.guiLabels.gotoPage
                                        + '&nbsp;<input type="text" id="goto_'+this.agentId+'" tabIndex="6" '
                                        + 'onKeyPress="if (event.keyCode==13) {'+agent+'.gotoPage(); return false}" '
                                        + 'size="3">&nbsp;'
                                        + '<input type="image" src="/rsrc/img/bt_right.gif" class="btNav" tabIndex="7" '
                                        + 'onClick="'+agent+'.gotoPage(); return false" alt="'+this.guiLabels.gotoPage+'">'
                                        + '</td>';
                                html += '</tr>'
                                + '</table>'
                                + '</div>'
                        + '</td>'
                        + '</tr>'}
                html += '<tr>';
                if (this.pageCount>0) {
                        html += '<td class="dictionary">';
                        if (this.isListView) {
                                for (var i=0; i<this.tuples.length; i++) {
                                        var eClass = (i%2!=0) ? "odd" : "even";
                                        var tLabel = '';
                                        var values = this.tuples[i].values;
                                        for (var j=0; j<this.sigIndices.length; j++) {
                                                if (tLabel.length>0) tLabel += this.sigSep;
                                                tLabel += values[this.sigIndices[j]]}
                                        var eTitle = (this.guiLabels.select+" "+tLabel).substr(0,80);
                                        html += '<a href="javascript:'+agent+'.select(' +this.tuples[i].id + ')" class="'
                                        + eClass+'" title="'+eTitle+'" tabIndex="1'+i+'">' + tLabel + '</a>';}}
                        else {
                                html += '<table class="wide">'
                                + '<thead>'
                                + '<tr>';
                                for (var i=0; i<this.tableFields.length; i++) {
                                        html += '<th>' + this.tableFields[i].firstChild.data + '</th>'}
                                html += '</tr>'
                                + '</thead>'
                                + '<tbody>'
                                for (var i=0; i<this.tuples.length; i++) {
                                        var eClass = (i%2!=0) ? "odd" : "even";
                                        var tLabel = '', trInner = '';
                                        var values = this.tuples[i].values;
                                        for (var j=0; j<this.sigIndices.length; j++) {
                                                if (tLabel.length>0) tLabel += this.sigSep;
                                                tLabel += values[this.sigIndices[j]]}
                                        var eTitle = (this.guiLabels.select+" "+tLabel).substr(0,80);
                                        html += '<tr onClick="'+agent+'.select(' +this.tuples[i].id + ')" onMouseOver="' + agent + '.setRow(this)" class="' + eClass+'" title="'
                                        + eTitle + '" tabIndex="1'+i+'">';
                                        for (var j=0; j<values.length; j++) {
                                                html += '<td>' + values[j] + '</td>'}
                                        html += '</tr>'}
                                html += '</tbody></table>'}
                html += '</td>'}
                else html += '<td class="noEntries">' + this.guiLabels.noResults+ '</td>';
                html += '</tr>'
                + '<tr>'
                + '<td align="center" class="pbuts">'

                + '<div class="perror"';
                if (!this.errorMsg)  html += ' style="display: none"';
                html += this.errorMsg + '></div>'
                + '<table summary="' + this.guiLabels.actionButtons + '">'
                + '<tr>'
                + '<td><button onClick="'+agent+'.deleteItem(); return false" tabIndex="998">'
                + this.guiLabels.Delete + '</button></td>'
                + '</tr>'
                + '</table>'
                + '</td>'
                + '</tr>'
                + '</table>';

                return html}
}
