flykit.namespace("flykit.apps.byexpressionprofile");

flykit.apps.byexpressionprofile.CustomGeneFinderRenderer = function() {};
flykit.apps.byexpressionprofile.CustomGeneFinderRenderer.prototype = new flykit.genefinder.DefaultRenderer(); 

/**
 * @private
 * Render the results summary pane.
 * @param {String} query the user's query
 * @param {Number} count number of results found
 */
flykit.apps.byexpressionprofile.CustomGeneFinderRenderer.prototype._renderResultsSummary = function( query, count ) {
    var _context = "flykit.genefinder.DefaultRenderer.prototype._renderResultsSummary";
    try {
        
        if (query instanceof Array) {
            flykit.debug("found array query", _context);
            query = query.join(", ");
        }
        var content = "found ";
        content += count;
        content += " matching <em>D. melanogaster</em> gene";
        content += (count == 0 || count > 1) ? "s " : " ";
        content += "from <a href='http://flybase.org'>flybase.org</a> ("+flykit.flybase.provenance+") ...";
        this._resultsSummaryPane.innerHTML = content;
        
    } catch (e) {
        flykit.debug("caught "+e.name, ", "+e.message, _context);
        throw new flykit.UnexpectedException(_context, e);
    }   
};


/**
 * @class
 * @constructor
 */
flykit.apps.byexpressionprofile.Application = function() {
	
	var that = this;
	
	var flyatlasprofile = null;
	var genefinder = null;
    var flyatlas = null;
    var flyted = null;
    var bdgp = null;
	var flybasepub = null;
//    var limit = 10000;
	
	this.initQueryTable = function() {
	    /*
        <table>
            <thead>
                <tr><th>brain</th></tr>
            </thead>
            <tbody>
                <tr>
                    <td><select id="select_brain_change"><option value="any">any</option><option value="up">up</option><option value="down">down</option><option value="nochange">no change</option></select></td>
                </tr>
            </tbody>
        </table>
	     */
	     var content = "<table><thead><tr>";
	     for (var i=1;i<flykit.flyatlas.tissues.length;i++) {
	         var tissue = flykit.flyatlas.tissues[i];
	         content += "<th>"+tissue+"</th>";
	     }
	     content += "</tr></thead><tbody><tr>";
	     
         /*for (var i=1;i<flykit.flyatlas.tissues.length;i++) {
             var tissue = flykit.flyatlas.tissues[i];
             content += "<td><select id=\"select_"+tissue+"_change\"><option value=\"any\">any</option><option value=\"Up\">up</option><option selected=\"selected\" value=\"Down\">down</option><option value=\"None\">none</option></select></td>";
         }*/
         content += "<td><select id=\"select_brain_change\">" +
             "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
             "<option selected=\"selected\" value=\"Down\">down</option>" +
             "<option value=\"None\">none</option></select></td>";
             
        content += "<td><select id=\"select_head_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
         
        content += "<td><select id=\"select_crop_change\">" +
             "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
             "<option selected=\"selected\" value=\"Down\">down</option>" +
             "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_midgut_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_hindgut_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
        
        content += "<td><select id=\"select_tubule_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_ovary_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_testis_change\">" +
            "<option value=\"any\">any</option><option selected=\"selected\" value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_acc_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_l_tubule_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_l_fatbody_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_ta_ganglion_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_carcass_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_sgland_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
                
        content += "<td><select id=\"select_l_sgland_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
            
        content += "<td><select id=\"select_l_midgut_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_l_hindgut_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_sptv_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_sptm_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_lcns_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_afb_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_lcar_change\">" +
            "<option selected=\"selected\" value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_eye_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_heart_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_lftrachea_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";

        content += "<td><select id=\"select_s2cells_change\">" +
            "<option value=\"any\">any</option><option value=\"Up\">up</option>" +
            "<option selected=\"selected\" value=\"Down\">down</option>" +
            "<option value=\"None\">none</option></select></td>";
             
	     content += "</tr></tbody></table>";
	     $("#queryTableContainer").html(content);
	}
	
	
	this.initFlyatlasProfile = function() {
	    var context = "flykit.apps.byexpressionprofile.Application.initFlyatlasProfile";
	    try {

            flykit.debug("instantiate a service for the flyatlas profile widget", context);
            var service = new flykit.flyatlas.Service();
            service.setEndpoint("../../../conf/flyatlas");
            
            flykit.debug("instantiate a renderer for the batchgenefinder widget", context);
            var renderPane = $("#flyatlasProfileWidget");
            var renderer = new flykit.flyatlas.ProfileWidget.DefaultRenderer(); // default renderer
            renderer.setCanvas(renderPane);
            
            flykit.debug("instantiate a flyatlas profile widget", context);
            flyatlasprofile = new flykit.flyatlas.ProfileWidget(service, renderer);
	        
        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
	}
		
    this.initGeneFinder = function() {
        try {
            // initialise genefinder widget
    
            flykit.info("instantiate a service for the genefinder widget");
            var service = new flykit.flybase.Service("../../../conf/flybase");
            
            flykit.info("instantiate a renderer for the genefinder widget");
            var renderPane = document.getElementById("geneFinderWidget");
//            var renderer = new flykit.genefinder.DefaultRenderer(); // default renderer
            var renderer = new flykit.apps.byexpressionprofile.CustomGeneFinderRenderer();
            renderer.setCanvas(renderPane);
            
            flykit.info("instantiate a genefinder widget");
            genefinder = new flykit.genefinder.Widget(service, renderer);
            
        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
    };

	this.initFlybasepub = function(){
		 try {
	        
            flykit.info("instantiate a service for the flybase publication widget");
            var service = new flykit.flybasepub.Service();
            service.setEndpoint("../../../conf/flybase");
            
            flykit.info("instantiate a renderer for the flybase publication widget");
            var renderer = new flykit.flybasepub.PublicationWidget.SimpleRenderer(); 
            renderer.setCanvas($("#flybasepubPublicationWidget"));
            
            flykit.info("instantiate a flybase publication widget");
            flybasepub = new flykit.flybasepub.PublicationWidget(service, renderer);
            
        } catch (error) {
            flykit.apps.publicationmashup.handleError(error);
        }
	};
        
    // called by this.init
    
    this.initFlyatlas = function() {
        try {
            
            flykit.info("instantiate a service for the flyatlas widget");
            var service = new flykit.flyatlas.Service();
            service.setEndpoint("../../../conf/flyatlas");
            
            flykit.info("instantiate a renderer for the flyatlas widget");
            var renderer = new flykit.flyatlas.Widget.DefaultRenderer(); 
            renderer.setCanvas($("#flyatlasWidget"));
            
            flykit.info("instantiate a flyatlas widget");
            flyatlas = new flykit.flyatlas.Widget(service, renderer);
            
        } catch (error) {
            flykit.apps.expressionmashup.handleError(error);
        }
    };
    
    // called by this.init
    
    this.initFlyted = function() {
        try {
            
            flykit.info("instantiate a service for the flyted image widget");
            var service = new flykit.flyted.Service("../../../conf/flyted");
            
            flykit.info("instantiate a renderer for the flyted image widget");
            var renderPane = document.getElementById("flytedImageWidget");
//            var renderer = new CustomFlytedRenderer();
            var renderer = new flykit.flyted.ImageWidget.DefaultRenderer();
            renderer.setCanvas(renderPane);
            
            flykit.info("instantiate a flyted image widget");
            flyted = new flykit.flyted.ImageWidget(service, renderer);
            
        } catch (error) {
            flykit.apps.expressionmashup.handleError(error);
        }
    };
    
    // called by this.init
    
    this.initBdgp = function() {
        try {
            
            flykit.info("instantiate a service for the bdgp image widget");
            var service = new flykit.bdgp.Service("../../../conf/bdgp");
            
            flykit.info("instantiate a renderer for the bdgp image widget");
            var renderPane = document.getElementById("bdgpImageWidget");
//            var renderer = new CustomBdgpRenderer();
//            var renderer = new flykit.bdgp.ImageWidget.DefaultRenderer();
            var renderer = new flykit.bdgp.ImageWidget.CompactRenderer();
            renderer.setCanvas(renderPane);
            
            flykit.info("instantiate a bdgp image widget");
            bdgp = new flykit.bdgp.ImageWidget(service, renderer);
            
        } catch (error) {
            flykit.apps.expressionmashup.handleError(error);
        }
    };
    
    this.init = function() {
        var context = "flykit.apps.byexpressionprofile.Application.init";
        try {
    		
    		var logReader = new YAHOO.widget.LogReader("logger");

            this.initQueryTable();
            this.initFlyatlasProfile();
            this.initGeneFinder();
            this.initFlyatlas();
            this.initFlyted();
            this.initBdgp();
            this.initFlybasepub();

            flykit.debug("hook form submission to widget call", context);
            YAHOO.util.Event.addListener("queryForm", "submit", this.onFormSubmitted);
            
            flykit.debug("add listener for results received event", context);
            flyatlasprofile.subscribe("RESULTSRECEIVED", this.onResultsReceived, null);
            
            // attach gene selection listener to genefinder
            genefinder.subscribe("GENESELECTED", this.onGeneSelected, null);

    		flykit.debug("application loaded, showing main pane", context);
    		$("#loadingPane").hide();
    		$("#applicationPane").show();
    		
    		that.initState();
    		
        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
	};
	
	this.onFormSubmitted = function(event) {
        var context = "flykit.apps.byexpressionprofile.Application.onFormSubmitted";
        try {
            flykit.debug("form submitted", context);
            var profile = {};
            
            flykit.debug("build profile object", context);
            for (var i=1;i<flykit.flyatlas.tissues.length;i++) {
                var tissue = flykit.flyatlas.tissues[i];
                var selectid = "select_"+tissue+"_change";
                var select = document.getElementById(selectid);
                var value = select.value;
                flykit.debug("found value "+value+" for select "+selectid, context);
                profile[tissue] = value;
            }
            that.setQueryState(profile);
            
            var limit = document.getElementById("queryLimit").value;
            that.doQuery(profile, limit);
            
        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
	    
	};

    this.doQuery = function(profile, limit) {
        var context = "flykit.apps.byexpressionprofile.Application.doQuery";
        try {
            $("#errorMessage")
               .hide()
               .html("this should never be visible");
            $("#geneFinderWidget").hide();
            $("#flyatlasWidget").hide();
            $("#flytedImageWidget").hide();
            $("#bdgpImageWidget").hide();

            flykit.debug("initiate request for probes and genes by profile", context);
            flykit.debug("limit: "+limit, context);
            flyatlasprofile.getProbesAndGenesByExpressionProfile(profile, limit);
            
        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
    }

    this.setQueryState = function(profile) {
        var context = "flykit.apps.byexpressionprofile.Application.setQueryState";
        try {
            
            var statestring = "";
            for (var tissue in profile) {
                statestring += tissue + ":" + profile[tissue] + "|";
            }
            
            var url = new String(window.location.href);
            var term = url.indexOf("#");
            if (term > 0) {
                url = url.substring(0, term);
            }
            window.location.href = url + "#query=" + escape(statestring);
        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
    };
    
    this.initState = function() {
        var context = "flykit.apps.byexpressionprofile.Application.initState";
        try {
    
            var url = new String(window.location.href);
            var qi = url.indexOf("#query=");
            
            if (qi > 0) {
                var end = url.length;
                var statestring = unescape(url.substring(qi+7,end));
                flykit.info("found query: "+statestring);
                var profile = {};
                var params = statestring.split("|");
                for (var i=0;i<params.length;i++) {
                    var param = params[i];
                    var vals = param.split(":");
                    if (vals[0].length > 0) {
                        profile[vals[0]] = vals[1];
                        var selectid = "select_"+vals[0]+"_change";
                        flykit.debug(selectid, context);
                        document.getElementById(selectid).value = vals[1];
                    }
                }
                var limit = document.getElementById("queryLimit").value;
                that.doQuery(profile, limit);
            }
            
        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
    };

    

    this.onResultsReceived = function(type, args) {
        try {
            flykit.debug("application: results received");
            var results = args[0];
            var flybaseids = results.genes;
            
            genefinder.findGenesByAnyNameBatch(flybaseids);
            $("#geneFinderWidget").show();

        } catch (error) {
            flykit.apps.byexpressionprofile.handleError(error);
        }
    };
    
    this.onGeneSelected = function(type, args) {
        try {
            var gene = args[0];
            flykit.info("gene selected: "+gene+" "+gene.flybaseID);
            flyatlas.getAssaysByGene(gene);
            flyted.findImagesByGene(gene);
            bdgp.findImagesByGene(gene);
            flybasepub.findPublicationsByGene(gene)
            $("#flyatlasWidget").show();
            $("#flytedImageWidget").show();
            $("#bdgpImageWidget").show();
//            that.setSelectionState(gene);
        } catch (error) {
            flykit.apps.expressionmashup.handleError(error);
        }
    };  
    	
	this.init();
};

flykit.apps.byexpressionprofile.handleError = function(error) {
    flykit.err(error.name+" :: "+error.message);
    $("#errorMessage")
       .html("an error has occurred, please see the log for more details")
       .show();
};
    

// on dom ready, instantiate application
YAHOO.util.Event.onDOMReady(function() {new flykit.apps.byexpressionprofile.Application();});
