
EVO.extend("display", function () {
   //*****************************************
   //these are PRIVATE functions and variables
   //*****************************************
   var timeDelay=1000; //time to delay between simulation cycles
   
   var processDivStore={}; //stored by process id
   var speciesDivStore={}; //stored by process id
   var currentlyDisplayedProcess=null;
   var markerWidth=0;
   var markerHeight=0;
   
   function calculateMarkerSize() {
      var screenwidth = jQuery("div#gridContainer").width();
      var screenheight = jQuery("div#gridContainer").height();
      markerWidth = Math.round(screenwidth/EVO.environment.getGridX());
      markerHeight = Math.round(screenheight/EVO.environment.getGridY());
      
      var processes = EVO.environment.getCurrentProcesses();
      var marker, process;
      for (var ii =0; ii < processes.length; ii+=1) {
         process = processes[ii];
         marker = processDivStore[process.id];
         marker.css({top:markerHeight*process.gridY,
                     left:(markerWidth*process.gridX),
                     height: markerHeight-1,
                     width: markerWidth-1});
      } 
   }
   
   function processCreateHandler(e,process) {
      e.stopPropagation();
      console.log(e, process.id, process.gridX, process.gridY);
      jQuery("div#gridDisplay").append('<div class="process" id="'+process.id+'">&nbsp;</div>');
      var divMarker=jQuery("div#gridDisplay div.process:last");
      divMarker.bind("click", process, divClickedHandler);
      divMarker.css({top:markerHeight*process.gridY,
                     left:(markerWidth*process.gridX),
                     height: markerHeight-1,
                     width: markerWidth-1,
                     background: process.species.colour});
      processDivStore[process.id]=divMarker;
      
   }
   
   function processMoveHandler(e,process) {
      e.stopPropagation();
      //console.log(e, process.id, process.gridX, process.gridY);
      processDivStore[process.id].stop(); //removes all current animations
      processDivStore[process.id].animate({top:markerHeight*process.gridY,
                             left:markerWidth*process.gridX});
   }

   function processKillHandler(e,process) {
      e.stopPropagation();
      //console.log(e);
      processDivStore[process.id].fadeOut("normal",function(){jQuery(this).remove();});
      delete processDivStore[process.id];
   }

   function speciesCreateHandler(e,species) {
      console.log(e, species);
      e.stopPropagation();
      jQuery("div#speciesList").append('<div class="species" id="'+species.id+'">'+species.id+'</div>');
      var divMarker=jQuery("div#speciesList div.species:last");
      divMarker.css({background:species.colour});
      speciesDivStore[species.id]=divMarker;
   }

   function speciesExtinctHandler(e,species) {
      console.log(e, species);
      e.stopPropagation();
      speciesDivStore[species.id].fadeOut("normal",function(){jQuery(this).remove();});
      delete speciesDivStore[species.id];
   }

   function divClickedHandler(e) {
      e.stopPropagation();
      //console.log(e, e.data);
      currentlyDisplayedProcess = e.data;
      updateProcessDisplay();
   }

   function updateProcessDisplay() {
      if (currentlyDisplayedProcess) {
         jQuery("div#processDetails div.id").html(currentlyDisplayedProcess.id);
         jQuery("div#processDetails div.cputime").html(currentlyDisplayedProcess.cputime);
         jQuery("div#processDetails div.activeThreadCount").html(currentlyDisplayedProcess.threads.length);
      }
   
   }

   //*****************************************
   //these are Lifecycle Events
   //*****************************************
   jQuery(document).ready(function() {
      jQuery(document).bind(EVO.environment.EVENT_PROCESS_CREATED,processCreateHandler);
      jQuery(document).bind(EVO.environment.EVENT_PROCESS_MOVED,processMoveHandler);
      jQuery(document).bind(EVO.environment.EVENT_PROCESS_KILLED,processKillHandler);
      jQuery(document).bind(EVO.environment.EVENT_SPECIES_CREATED,speciesCreateHandler);
      jQuery(document).bind(EVO.environment.EVENT_SPECIES_EXTINCT,speciesExtinctHandler);
      
      jQuery(document).ready(calculateMarkerSize);
      jQuery(window).resize(calculateMarkerSize);
      jQuery(document).bind(EVO.indexHtml.EVENT_PAGE_READY, function(){
         EVO.indexHtml.LAYOUT_HOLDER.on('resize', calculateMarkerSize);
         });      
      });

   //*****************************************
   //these are PUBLIC functions and variables
   //*****************************************

   return {
      updateDisplay: function() {
         jQuery("div#loopCount").html(""+EVO.environment.getLoopCount());
         jQuery("div#processCount").html(""+EVO.environment.getProcessCount());
         var instrsPerSec = EVO.vm.getInstrCount() / ((Number(new Date())-EVO.environment.getStartTime())/1000);
         jQuery("div#instrRate").html(""+Math.round(instrsPerSec*100)/100);

         updateProcessDisplay();

         if (EVO.environment.isRunning()) {
            setTimeout(function(){EVO.display.updateDisplay();},timeDelay);
         }
      }
   };
}());
