/* Copyright 2007 You may not modify, use, reproduce, or distribute this software except in compliance with the terms of the License at:
 http://developer.sun.com/berkeley_license.html
 $Id: component.js,v 1.0 2007/04/15 19:39:59 gmurray71 Exp $
*/

dojo.require("dojox.grid.VirtualGrid");
dojo.require("dojox.grid._data.model");
dojo.require("dojox.grid.Grid");

// define the namespaces
jmaki.namespace("jmaki.widgets.dojo.dijit.grid");

jmaki.widgets.dojo.dijit.grid.Widget = function (wargs) {
    var _widget = this;
    var columns = [];

    var uuid = wargs.uuid;
    var topic = "/dojo/dijit/grid";
    var subscribe = ["/dojo/dijit/grid", "/table"];
    var filter = "jmaki.filters.tableModelFilter";
    
    var container = document.getElementById(uuid);
    var table;
    var counter = 0;   
    var wrapper;
    var model;
    
    function genId() {
        return wargs.uuid + "_nid_" + counter++;
    }


        
    // private funciton to initialize the widget
   function init() {
        var subrow = [];
        if (columns) {
           for (var i=0; i< columns.length; i++) {
               var c = columns[i].label;
               var id = columns[i].id;
               subrow[i] = {name: c, field: id};
           }
        }   
        // set the view per Dojo's grid widget
        
        var view = {
            rows: [ subrow ]
        };

        var _structure = [
            view
        ];
        
         var container = document.getElementById(uuid);
         if (typeof _widget.rows != "undefined") {
             model = new dojox.grid.data.Objects(null, _widget.rows);
             wrapper = new dojox.Grid({
 	                                id: uuid+"_widget",
 	                                model: model,
 	                                structure: _structure,
                                        autoWidth:true
 	                        }, container);
                                 
         }else {
             wrapper = new dojox.Grid({id: uuid+"_widget", structure: _structure, autoWidth : true},container);
         }
         // set to sort on 1st column
         wrapper.setSortIndex(1, true);
         wrapper.render();
         // want to know if the user clicks on a row so we can publish the data
         dojo.connect(wrapper.selection, "addToSelection", _widget, "onSelect");

    }

    this.clearFilters = function(){
        table.clearFilters();
    }
    /**
     *  Clear all the data from the grid.
     *
     */
    this.clear = function() {
        model.clearData();  
        wrapper.render();
        counter = 0;
    };
    
    // private function that gets the row index given the targetId.
    function getRowIndex(targetId){
        for (var i=0; i< model.data.length; i++) {
            if (targetId == model.data[i].id)
                return i;
        }
    }
    /**
     *  removeRow removes a row from the grid.
     *
     * @param b - The targetId of the row to be removed or an object containing a
                  message.targetId property like:
                  { messsage : {targetId : 'foo'}}
     *
     */ 
    this.removeRow = function(b){
        var targetId;
        if (b.message)b = b.message;
        if (b.targetId) {
           targetId = b.targetId;
        } else {
            targetId = b;
        }    
        var row= getRowIndex(targetId);
        model._remove([row]);
        model.removal();
        wrapper.render();

    };
    /**
     *  updateRow updates a row in the grid.
     *
     * @param b - The targetId of the row to be updated or an object containing a
                  message.targetId property like:
                  { messsage : {targetId : 'foo', value: [rowdata]}}
     *
     */ 
    this.updateRow = function(b){
        var targetId;
        var data;
        if (b.message)b = b.message;
        if (b.targetId) {
           targetId = b.targetId;
        } else {
            targetId = b;
        }            
        if (b.value) { 
            data = b.value;
        }else {
           jmaki.log("No data for update, exiting...");
           return;
        }
        var rowIndex = getRowIndex(targetId);
        model.setRow(data, rowIndex);
        wrapper.render();

    };
    /**
     *  addRows add a set of rows to the grid.
     *
     * @param b - an array of objects containing the row data to be added.
                  the grid is sorted after rows are added.  Data is of the form:
                  { value : [{row 1 data},{row2 data]}
     *
     */ 
    this.addRows = function(b){
        if (b.message)b = b.message;
        /* this may be a better way to add rows 
        wrapper.beginUpdate();
        for (var i = 0; i < b.value.length ; i++) {
            jmaki.log("b.value[i] "+b.value[i]);
            wrapper.addRow(b.value[i]);
        }
        wrapper.endUpdate();
        */
        for (var i=0; i < b.value.length; i++) {
            _widget.addRow({ value : b.value[i]}, false);
        }        

        wrapper.sort();
        wrapper.refresh();
    };    
     /**
     *  addRow adds a row to the grid. The grid is sorted after the row is added.
     *
     * @param b - The row data to be added or an object containing a
                  message.value property like:
                  { messsage : {value : '[row data]}}
       @param sort - false if multiple rows are being added so the grid is only sorted 
     *             once.  If undefined the grid will be sorted.
     *
     */ 
    this.addRow = function(b, sort){
        var r;
        if (b.message)b = b.message;
        if (b.value) {
            r = b.value;
        } else {
            r = b;
        }
        var targetId;
        if (r.id) targetId = r.id;
       
        var row = getRowIndex(targetId);
        if (row ) var data = model.getRow(row);

        if ( data && data.id == targetId) {
            jmaki.log(wargs.uuid  + " : Warning. Attempt to add record to dojo.dijit.grid. with duplicate row id: " + targetId + ". Autogenerating new id.");
            r.id = genId();
        }
        
        // add an id for sorting if not defined
        if (typeof r.id == "undefined") {
            r.id = genId();
        }
        
        model.insert(r);
        if((typeof sort == 'undefined') ||
            (typeof sort == 'boolean' && 
             sort == true))  {
             wrapper.sort();
             wrapper.refresh();
         }      
     };
     
    /**
     *  Select an item from the list. The Label of the item will be
     *  set as the value of the text field.  
     *
     * @param o - The targetId to select or an object containing a
                  message.targetId property like:
                  { messsage : {targetId : 'foo'}}
     *
     */
    this.select = function(e){
        var targetId;
        var _target;
        if (e.message)e = e.message;
        if (e.value)e = e.value;

        if (e.action && e.action.targetId) {
           targetId = e.action.targetId;
        } else {
           targetId = e.targetId;
        }
        
        var row= getRowIndex(targetId);
        wrapper.selection.select(row);

    };
    /**
     *  onSelect event captured here so the data of the row selected can be published to a topic.
     *
     * @param e - The actual row data.
     *
     */    
     
    this.onSelect = function(e) {

         data = model.getRow(e);
        // later we may want to support multiple selections 
        jmaki.publish(topic + "/onSelect", { widgetId : wargs.uuid, type : 'onSelect', targetId : data.id, value : data });
    };
    
    function doSubscribe(topic, handler) {
        var i = jmaki.subscribe(topic, handler);
        _widget.subs.push(i);
    }
    /**
     *  destroy unsubscribe the event listeners.
     *
     */      
    this.destroy = function() {
        for (var i=0; _widget.subs && i < _widget.subs.length; i++) {
            jmaki.unsubscribe(_widget.subs[i]);
        }
    };
    /**
     *  postLoad set the subscribers for the event listeners, read the args if any, 
     *           get data for the grid if any and initialize the widget.
     *
     */    
    this.postLoad = function() {
        // track the subscribers so we can later remove them
        _widget.subs = [];
        for (var _i=0; _i < subscribe.length; _i++) {
            doSubscribe(subscribe[_i]  + "/clear", _widget.clear);
            doSubscribe(subscribe[_i]  + "/addRow", _widget.addRow);
            doSubscribe(subscribe[_i]  + "/addRows", _widget.addRows);
            doSubscribe(subscribe[_i]  + "/updateRow", _widget.updateRow);
            doSubscribe(subscribe[_i]  + "/removeRow", _widget.removeRow);
            doSubscribe(subscribe[_i]  + "/select", _widget.select);
        } 
        
        if (wargs.args) {
            if (wargs.args.topic) {
                topic = wargs.args.topic;
                jmaki.log("Dojo grid: widget uses deprecated topic property. Use publish instead. ");
            }

            if (wargs.args.filter) {
               filter = wargs.args.filter;
            }
        }

        if (wargs.publish ) {
            topic = wargs.publish;
         }

        if (wargs.subscribe){
            if (typeof wargs.subscribe == "string") {
                subscribe = [];
                subscribe.push(wargs.subscribe);
            } else {
                subscribe = wargs.subscribe;
            }
        }

        // set columns from the widget arguments if provided.
        if (wargs.args && wargs.args.columns) {
            columns = wargs.args.columns;     
        }    
                                // pull in the arguments
        if (wargs.value) {
            // convert value if a jmakiRSS type
            if (wargs.value.dataType == 'jmakiRSS') {
               wargs.value = jmaki.filter(wargs.value, filter);
            }
            if (!wargs.value.rows) {
                showModelDeprecation();
                return;
            }
            if (wargs.value.rows){
                _widget.rows = wargs.value.rows;
            } else if (wargs.value instanceof  Array) {
                _widget.rows = wargs.value;
            }
            if (wargs.value.columns) {
                columns = wargs.value.columns;
            }
            init();

        }else if (wargs.service) {
            dojo.xhrGet({
                url: wargs.service,
                handleAs: "json",
                load: function (type,data,evt) {
                    if (data == false) {
                        container.innerHTML = "Data format error loading data from " + wargs.service;
                    } else {
                        // convert value if a jmakiRSS type
                        if (data.dataType == 'jmakiRSS') {
                            data = jmaki.filter(data, filter);
                        }
                        if (!data.rows) {
                            showModelDeprecation();
                            return;
                        }
                        if (data.rows) {
                            _widget.rows = data.rows;                   
                        }
                        if (data.columns) {
                           columns = data.columns;
                        }
                    }
                    init();
                }
            });

        }  
     };
 }        
