<?xml version="1.0" encoding="UTF-8" ?>
<!-- dataset_selector.xml -->
<!-- Author: Ian Smith (imsmith@uw.edu) -->
<Module>

<!-- ** Replace inside quotes with your gadgets title -->
<ModulePrefs title="Dataset Selector"
    height="10"
    scrolling="true">
     <Require feature="dynamic-height"/>
     <Require feature="opensocial-0.9"/> 
     <Require feature="settitle"/>
     <Require feature="minimessage"/>
</ModulePrefs> 

<Content type="html"><![CDATA[

<!-- Add HTML content here -->
<div id="divSelector">
    <div id="divDataset_List">
    
    </div>

</div>

<link href="css/gadget.css" rel="stylesheet" type="text/css">

<!-- Used to register with the Data Gadget -->
<script src="js/DataInterface.js" type="text/javascript"></script>

<!-- Contains UW.astro objects -->
<script src="js/astroObjectLib.js" type="text/javascript"></script>
<script src="js/dataset.js" type="text/javascript"></script>


<script type="text/javascript">

var myGadget = null,
    DEBUG = false;


function debugLog(msg){ if(DEBUG){UW.astro.debugLog(GADGET_NAME + ": " + msg);}}

var GADGET_NAME = "Dataset_Selector" + "_" + Math.floor(Math.random()*100000).toString();

// Creates gadget object
function init(){
    gadgets.window.setTitle("Dataset Selector");
    myGadget = new datasetSelector();
    gadgets.window.adjustHeight();
}


function datasetSelector(){
    var my = new Object();
    // CONSTANTS
    

    var DS_DIV_PREFIX = "dsDiv_",
        DS_DIV_CLASSNAME = "dsListElement",
        DS_DIV_ID = "divDataset_List";
    
    // PRIVATE
    var _namespaceList = [ UW.astro.DEFAULT_NAMESPACE ];      // list of our current Namespaces
    
    // Private Helper Variables
    var di = new UW.astro.DataInterface(GADGET_NAME); // make dataInterface object, init with default

    // INIT
    
    // ** Variables to register go in this array. 
    var variableArray = ["Dataset_List"]; 
                            
    // ** Triggers to register go in this array
    // Each trigger is a 2-element array as follows:
    // [ "VariableName", triggerFunction ]
    // example with one trigger: (notice the array inside the array)
    //      var triggerArray = [ ["Viewport_Center_Coordinate", function(){ zoomMe() }] ]
    // it is recommended to define functions outside the array for more readable code
    var triggerArray = [ ["Dataset_List", updateDataset_List] ];
                           

    di.registerMe( { namespaceList : _namespaceList,
                    variableList : variableArray,  
                    triggerList : triggerArray,   
                } );
    
    // VARIABLES
    // array of dataset names that are currently displayed in list
    var _datasetsInList = [];
    
    // METHODS
    // ** Add public methods (that will be called from outside the object by a button or something) 
    
    // Adds any new datasets in the public dataset list to this gadgets list
    function updateDataset_List() {
        // clear the list
        //document.getElementById(DS_DIV_ID).innerHTML = "";

        
        var dsList = di.readVariable(UW.astro.DEFAULT_NAMESPACE, "Dataset_List");
        for (var i=0, len=dsList.length; i<len; i++) {
            var dsName = dsList[i];
            if (!arrayContains(_datasetsInList, dsName)) {
                di.registerVariable(dsName, null);
                di.registerTrigger(UW.astro.DEFAULT_NAMESPACE, dsName, function() {
                                            updateDSListElement(dsName);
                                        } );
                addDatasetToList(dsName);   
            }
        }
        gadgets.window.adjustHeight();
    }
   
    function updateDSListElement(dsName) {
        var divElem= document.getElementById(DS_DIV_PREFIX + dsName);
        // clear div
        while (divElem.hasChildNodes()) {
            divElem.removeChild(divElem.lastChild);
        }
        
        // add the div
        divElem.appendChild(createDSListElement(dsName));
    }
    
    // adds the creates a new dataset list element and adds it to the list
    function addDatasetToList(dsName) {
        // add this name to the array of currently displayed ds
        _datasetsInList.push(dsName);
        
        // create the div
        var dsOuterDiv = document.createElement("div");
        // TODO: Possibly dangerous to allow any chars in the ID
        dsOuterDiv.id = DS_DIV_PREFIX + dsName;
        dsOuterDiv.className = DS_DIV_CLASSNAME;

        dsOuterDiv.appendChild(createDSListElement(dsName));
        
        // append the div element to the list div
        document.getElementById(DS_DIV_ID).appendChild(dsOuterDiv);
    }
    
    // returns a div filled with dataset functions
    function createDSListElement(dsName) {
        var ds = di.readVariable(UW.astro.DEFAULT_NAMESPACE, dsName);
                
        var dsDiv = document.createElement("div");

        // create the visibility checkbox
        var ckVis = document.createElement("input");
        ckVis.type = "checkbox";
        ckVis.id = "ckVis_" + dsName;
        ckVis.checked = getDSVisibility(dsName);
        ckVis.onclick = function() {
                            toggleDSVisibility(dsName);
                        }
        dsDiv.appendChild(ckVis);
    
        // create the dataset name span
        var spanDSName = document.createElement("span");
        spanDSName.innerHTML = "<b>" + dsName + "</b> (" +  ds.getSize() + ")";
        dsDiv.appendChild(spanDSName);
        
        // create the shape selector
        
        // create the delete button

        // create a new div for color checkboxes and subsetting
        dsDiv.appendChild(createDSSubsetList(ds));
        
        return dsDiv;
               
    }
    
    // returns a div containing the color subsetting functionality to add to
    // the DS list
    function createDSSubsetList(ds) {
        var dsName = ds.getName();
        var subDiv = document.createElement("div");
        var colorList = ds.getUniqueColors();
        
        // indent the colors
        var spanIndent = document.createElement("span");
        spanIndent.innerHTML = "&nbsp; \\-";
        subDiv.appendChild(spanIndent);
        
        // create the color name span
        // for each color, make a checkbox and name
        for (var i=0, len=colorList.length; i<len; i++) {
            var color = colorList[i];
            
            // make checkbox
            var ckVis = document.createElement("input");
            ckVis.type = "checkbox";
            ckVis.id = "ckVis_" + dsName + "_" + color;
            ckVis.checked = getDSVisibility(dsName);
            ckVis.value = color;
            ckVis.onclick = function() {
                            toggleDSColorVisibility(dsName, this.value, this.checked);
                        }
            subDiv.appendChild(ckVis);
            
            // create the color name span
            var spanColor = document.createElement("span");
            spanColor.style.marginRight = "8px";
            spanColor.innerHTML = color;
            if (color === "") {
                spanColor.innerHTML = "default";
            }
            spanColor.innerHTML += " (" + ds.getColorIndexes(color).length + ")";
            subDiv.appendChild(spanColor);
        }

        // create subset button
        var aSubset = document.createElement("input");
        aSubset.type = "button";
        aSubset.value = "copy";
        aSubset.onclick = function(){
                            subsetByVisible(dsName);
                        }
        aSubset.style.cssFloat = "right";
        subDiv.appendChild(aSubset);

        return subDiv;
    }
    
    function subsetByVisible(dsName) {

        var ds = di.readVariable(UW.astro.DEFAULT_NAMESPACE, dsName);
        
        // copy the records from the dataset
        var subsetData = ds.db.get({db_visible:true});
        
        // make the new dataset
        var subsetDS = new UW.astro.Dataset(subsetData);
        // get the new name
        var newName = prompt("Enter name for new dataset");
        if (newName === "" || newName === null) {
            return;
        }
        subsetDS.setName(newName);
        
        // make it public
        di.registerVariable(newName, null);
        di.writeVariable(UW.astro.DEFAULT_NAMESPACE, newName, subsetDS);
        
        // update the datasetList
        var dsList = di.readVariable(UW.astro.DEFAULT_NAMESPACE, "Dataset_List");
        dsList.push(newName);
        di.writeVariable(UW.astro.DEFAULT_NAMESPACE, "Dataset_List", dsList);
        // call to refresh the list
        updateDataset_List();
        
    }
    // HELPER
    function getDSVisibility(dsName) {
        var ds = di.readVariable(UW.astro.DEFAULT_NAMESPACE, dsName);
        return ds.getVisible();
    }
    function toggleDSVisibility(dsName) {
        var ds = di.readVariable(UW.astro.DEFAULT_NAMESPACE, dsName);
        ds.setVisible(!ds.getVisible());
        di.writeVariable(UW.astro.DEFAULT_NAMESPACE, dsName, ds);
    }
    function toggleDSColorVisibility(dsName, color, vis) {
        var ds = di.readVariable(UW.astro.DEFAULT_NAMESPACE, dsName);
        ds.setIndexesVisible(ds.getColorIndexes(color), vis);
        di.writeVariable(UW.astro.DEFAULT_NAMESPACE, dsName, ds);
    }

    // returns true if arr contains el
    function arrayContains(arr, el) {
        for (var i=0, len=arr.length; i<len; i++) {
            if (arr[i] === el) {
                return true;
            }
        }
        return false;
    }
    return my;
}

gadgets.util.registerOnLoadHandler(init); 

</script>

]]></Content>
</Module>

