      google.load('visualization', '1', {packages: ['table', 'motionchart', 'annotatedtimeline']});
//all the crap within the $(document).ready function is just menu manipulation.  It just establishes the interedependencies of the select menus based on the classes of the select objects.  It also tells the pop-up blurb things to come up.
      $(document).ready(function(){

/*        $("#firstVar").tooltip({
          delay: 0,
          bodyHandler: function() {
            var newInd="";
            $(this).find("option:selected").each(function(){
                newInd=$(this).val();
            });
            return variableBlurbs[newInd][1];
          },
          showURL: false,
          top: -55,
          right: 100,
          track: true
        });
        $("#secondVar option").tooltip({
          bodyHandler: function() {
            return variableBlurbs[$(this).val()][1];
          }
        });
        $("#firstDataSet option").tooltip({
          bodyHandler: function(){
            return dataSetBlurbs[$(this).val()][1];
          }
        });*/
        ShowPopup(dataSetBlurbs["graphUtilDefault"][1]);
        var optionList="http://cimearth.org/index.php/cim-earth/optionList";
        

        $("#firstVar").keypress(
          function(){
            ShowPopup("<font color=red>Please use the mouse to select this option</font>");           
          }
        );
        $("#firstVar").blur(
          function(){ShowPopup("");}
        );

        $("#firstVar").change(function () {
          adjustTotalPrompt();
          adjustDataTypes("#firstVar", "#first_data_type");
        }); 
        
/*        $("#secondVar").load(
          optionList,
          {'defaultHTML':'<option value=motionChartDefault>Choose Variable to Display</option>'}, 
          function(){
            $("#secondVar option").hover(
             function(){
               ShowPopup(variableBlurbs[$(this).val()][1]);
             },
             function(){
             });      
          }
        );*/
        $("#secondVar").keypress(
          function(){
            ShowPopup("<font color=red>Please use the mouse to select this option</font>");           
          }
        );
        $("#secondVar").blur(
          function(){ShowPopup("");}
        );
        $("#secondVar").change(function(){
          adjustTotalPrompt();
          adjustDataTypes("#secondVar", "#second_data_type");
        });

        $("#firstDataSet option").hover(
          function(){
            ShowPopup(dataSetBlurbs[$(this).val()][1]);
          },
          function(){
          }
        );
        $("#firstDataSet").keypress(
          function(){
            ShowPopup(dataSetBlurbs[$(this).val()][1]);
          }
        );
        $("#firstDataSet").change(function(){
          clearSelect("first_data_type");
          clearSelect("firstVar");
          $("#first_data_type option:not(:first)").css("visibility", "hidden");
          $("#first_data_type option:not(:first)").css("display", "none");
//          adjustVars("first_data_type", "#firstVar", $(this).val());
          $("#firstVar").load(
            optionList,
            {'defaultHTML':'<option value=motionChartDefault>Choose Variable to Display</option>', 'setClass':$("#firstDataSet").val()}, 
            function(){
              $("#firstVar option").hover(
               function(){
                 ShowPopup(variableBlurbs[$(this).val()][1]);
               },
               function(){
               });      
            }
          );         
        });
        
        $("#secondDataSet option").hover(
          function(){
            ShowPopup(dataSetBlurbs[$(this).val()][1]);
          },
          function(){
          }
        );
        $("#secondDataSet").keypress(
          function(){
            ShowPopup(dataSetBlurbs[$(this).val()][1]);
          }
        );
        $("#secondDataSet").change(function(){
          clearSelect("second_data_type");
          clearSelect("secondVar");
          $("#second_data_type option:not(:first)").css("visibility", "hidden");
          $("#second_data_type option:not(:first)").css("display", "none");
//          adjustVars("second_data_type", "#secondVar", $(this).val());
          $("#secondVar").load(
            optionList,
            {'defaultHTML':'<option value=motionChartDefault>Choose Variable to Display</option>', 'setClass':$("#secondDataSet").val()}, 
            function(){
              $("#secondVar option").hover(
               function(){
                 ShowPopup(variableBlurbs[$(this).val()][1]);
               },
               function(){
               });      
            }
          );                  
        });





        $("#first_data_type").change(adjustTotalPrompt);
        $("#first_data_type").keypress(
          function(){
            ShowPopup("<font color=red>Please use the mouse to select this option</font>");
          }
        );
        $("#first_data_type").blur(
          function(){ShowPopup("");}
        );
        $("#first_data_type option").hover(
          function(){
            ShowPopup("");
          },
          function(){}
        );

        $("#second_data_type").change(adjustTotalPrompt);
        $("#second_data_type").keypress(
          function(){
            ShowPopup("<font color=red>Please use the mouse to select this option</font>");
          }
        );
        $("#second_data_type").blur(
          function(){ShowPopup("");}
        );
        $("#second_data_type option").hover(
          function(){
            ShowPopup("");
          },
          function(){}
        );
        
                
        document.getElementById("firstVar").selectedIndex=0;
        document.getElementById("secondVar").selectedIndex=0;
        document.getElementById("first_data_type").selectedIndex=0;
        document.getElementById("second_data_type").selectedIndex=0;
        document.getElementById("firstDataSet").selectedIndex=0;
        document.getElementById("secondDataSet").selectedIndex=0;

        
      });
      function adjustTotalPrompt(){
        var bothGross=(($("#first_data_type").val()=="gross")&&($("#second_data_type").val()=="gross"));
        var bothHaveTotalAtt=(($("#firstVar option:selected").hasClass("total"))&&($("#secondVar option:selected").hasClass("total")));
        if(bothGross&&bothHaveTotalAtt){
          $("#total_prompt").css("visibility", "visible");
          $("#total_prompt").css("display", "");
        }
        else{
          $("#totalPrompt").css("visibility", "hidden");
          $("#totalPrompt").css("display", "none");
        }
      }
      function adjustVars(dataId, varId, selectorString){
        document.getElementById(dataId).selectedIndex=0;
        $(varId).find("option:not(:first)").each(function(){
          if($(this).hasClass(selectorString)){
            $(this).css("visibility", "visible");
            $(this).css("display",""); 
          }
          else{
            $(this).css("visibility", "hidden");
            $(this).css("display", "none");
          }
            
        });
      }
      function adjustDataTypes(varId, typeId){//if the option selected has a given class, set the corresponding data type to visible, else make it invisible.
        var doGlobalShare="";
        var doGross="";
        var doPerCapita="";
        $(varId+" option:selected").each(
          function(){   
            if($(this).hasClass("globalShare"))
              doGlobalShare="true";   
            if($(this).hasClass("gross"))
              doGross="true";
            if($(this).hasClass("perCapita"))
              doPerCapita="true";
          }
        );
        
        $(typeId).load(
          "http://cimearth.org/index.php/cim-earth/dataTypeList",
          {"doGlobalShare":doGlobalShare, "doGross":doGross, "doPerCapita":doPerCapita},
          function(){
          }
        );        
      }

 



 
      function clearSelect(id){
        document.getElementById(id).selectedIndex=0;
        $("#"+id+" option:not(:first)").css("display","none");
        $("#"+id+" option:not(:first)").css("visibility","hidden");
/*        document.getElementById(id).options[0].style.display="";
        document.getElementById(id).options[0].style.display="";
        document.getElementById(id).options[0].style.visibility="visible";
        document.getElementById(id).options[0].style.visibility="visible";*/
      }

      
      function minimum(a,b){
        if(a<b)
          return a;
        else
          return b;
      }
      function scaleFirstDevs(fileName){
        if(fileName=="pop.csv")
          return false;
        else
          return true;

      }

      function fillChart(firstMeans, firstDevs, secondMeans, secondDevs, firstSelected, secondSelected, popString, unitsFirst, unitsSecond, firstTotal, secondTotal, firstTotalDevs, secondTotalDevs){
        var doFirstDevs=(firstDevs!="");
        var doSecondDevs=(secondDevs!="");
        var doTotal=((firstTotal!="")&&(secondTotal!=""));
        var doFirstTotalDevs=(doTotal&&(firstTotalDevs!=""));
        var doSecondTotalDevs=(doTotal&&(secondTotalDevs!=""));
        var x;
        var y;
        var firstArray=splitString(firstMeans);
        var firstErrArray=splitString(firstDevs);
        var secondArray=splitString(secondMeans);
        var secondErrArray=splitString(secondDevs);
        var popArray=splitString(popString);
        var firstTotal=splitString(firstTotal);
        var secondTotal=splitString(secondTotal);
        var firstTotalDevs=splitString(firstTotalDevs);
        var secondTotalDevs=splitString(secondTotalDevs);//see formLibrary.js.  splitString just turns the string located on the server into a 2by2 array.
        var i;
        var j;
        var numRegions=minimum(firstArray.length, secondArray.length);//this is stupid.  both should be of length 16.  unless you're doing dynamic regionation.  which will be complicated anyway.
        var numYears=minimum(firstArray[0].length, secondArray[0].length);
        var chartData = new google.visualization.DataTable();
        chartData.addColumn('string', 'Region')
        chartData.addColumn('date', 'Year');
        chartData.addColumn('number', firstSelected+" ("+units[unitsFirst]+")");
        chartData.addColumn('number', secondSelected+" ("+units[unitsSecond]+")");
        if(doFirstDevs)
          chartData.addColumn('number', "1 Std. Dev: "+firstSelected+" ("+units[unitsFirst]+")");
        if(doSecondDevs)
          chartData.addColumn('number', "1 Std. Dev: "+secondSelected+" ("+units[unitsSecond]+")");
        chartData.addColumn('number', "Population (Persons)");
        if(doTotal)
          chartData.addRows((numRegions+1)*numYears*1);//you have to add an extra numYears (61) rows if you are plotting totals.  this is pretty straightforward if you understand the way data gets stored for motionChart.
        else
          chartData.addRows(numRegions*numYears*1);
        for (i=0; i<numRegions; i++){//now for the motionChart
            for(j=0; j<numYears; j++){
            curRow=(((1*i)*(numYears*1))+(j*1));//arithmetic! works!
            chartData.setValue(curRow,0, "Region: " + longRegionArray[i]);
            chartData.setValue(curRow,1, new Date(((2003*1)+(j*1))*1,0,1));
            chartData.setValue(curRow,2,(firstArray[i][j])*1);
            chartData.setValue(curRow,3,(secondArray[i][j])*1);
            colInd=4;
            if(doFirstDevs)
              chartData.setValue(curRow,(colInd++),(firstErrArray[i][j])*1);
            if(doSecondDevs)
              chartData.setValue(curRow,(colInd++),(secondErrArray[i][j])*1);
            chartData.setValue(curRow,colInd,(popArray[i][j])*1);
          }
        }
        if(doTotal){
          for(j=0; j<numYears; j++){
            curRow++;
            chartData.setValue(curRow,0, "WORLD TOTAL");
            chartData.setValue(curRow,1, new Date(((2003*1)+(j*1))*1,0,1));
            if(doTotal){
              chartData.setValue(curRow,2,firstTotal[j]*1);
              chartData.setValue(curRow,3,secondTotal[j]*1);
            }
            colInd=4;
            if(doFirstTotalDevs && doFirstDevs)
              chartData.setValue(curRow, (colInd++), firstTotalDevs[j]*1);//this colInd++ stuff is just tricky BS to deal with the fact that certain sets of devs could possibly be missing.
            else if(doFirstDevs)
              chartData.setValue(curRow, (colInd++), 0);
            if(doSecondTotalDevs && doSecondDevs)
              chartData.setValue(curRow, (colInd++), secondTotalDevs[j]*1);
            else if(doSecondDevs)
              chartData.setValue(curRow, (colInd++), 0);

          }
        }
        return chartData;
      }


/*      function addTrailListener(motionchart, options, chartData){
        vizDiv=document.getElementById("visualization");
        google.visualization.events.addListener(
          motionchart,
          'statechange',
          function(){
            stateArray=eval('('+motionchart.getState()+')');
            if(stateArray['showTrails']){
              stateArray['showTrails']=false;
              alert(JSON.encode(stateArray));
              options['state']=JSON.encode(stateArray);
              alert("This feature is not yet available.");
              newchart = new google.visualization.MotionChart(vizDiv);
              google.visualization.events.addListener(
                newchart,
                'ready',
                function(){
                  addTrailListener(newchart, options, chartData)
                }
              );
              alert("pre");
              newchart.draw(chartData, options);
              alert('oost');
            }
          }
        );
      }

*/

      
      function drawVisualization(firstMeans, firstDevs, secondMeans, secondDevs, firstSelected, secondSelected, popString, unitsFirst, unitsSecond, firstTotal, secondTotal, firstTotalDevs, secondTotalDevs) {
        /*
        read the documentation for motionChart at the google viz api site.  especially on how data is stored.  it's kind of a stupid system.

        */
       
        var chartData = fillChart(firstMeans, firstDevs, secondMeans, secondDevs, firstSelected, secondSelected, popString, unitsFirst, unitsSecond, firstTotal, secondTotal, firstTotalDevs, secondTotalDevs);//take all the stuff and convert it to cram it into a dataTable for the viz util to read.
        var options = {};
        options['state'] = '{"dimensions":{"iconDimensions":["dim0"]},"nonSelectedAlpha":0.4,"orderedByX":false,"xZoomedDataMax":35845877.15935289,"iconType":"BUBBLE","showTrails":false,"uniColorForNonSelected":false,"yLambda":1,"duration":{"timeUnit":"D","multiplier":1},"yZoomedDataMax":35845877.15935289,"time":"2003","sizeOption":"5","xLambda":1,"xZoomedDataMin":93469.9482133468,"yZoomedDataMin":93469.9482133468,"stateVersion":3,"xAxisOption":"2","playDuration":15,"iconKeySettings":[],"yAxisOption":"3","yZoomedIn":false,"xZoomedIn":false,"orderedByY":false,"colorOption":"_UNIQUE_COLOR"};'//see the API for instructions on setting this option.
        options['width'] = 750;
        options['height'] = 500;
//        options['showSidePanel'] = false;
        var vizDiv = document.getElementById('visualization');
        var motionchart = new google.visualization.MotionChart(vizDiv);
        motionchart.draw(chartData, options);//this is where the drawing happens.
//        addTrailListener(motionchart, options, chartData);
        google.visualization.events.addListener(
          motionchart,
          'statechange',
          function(){
            stateArray=JSON.parse(motionchart.getState());
            if(stateArray['showTrails']){
              stateArray['showTrails']=false;
//              alert(JSON.stringify(stateArray));
              stateArray=JSON.stringify(stateArray);
              options['state']=stateArray;
              alert("This feature is not yet available.");
              motionchart.draw(chartData, options);
            }
          }
        );

        document.getElementById('userOptions').innerHTML="<p>Note that you can adjust the axes to display data on a logarithmic scale.  You can also choose what the size of the dots represents (uncertainties, etc).  Also, you can use the tab in the upper right corner of the visualization to switch into graph mode.  Finally, note that you can select which countries you are plotting by using the Select menu immediately to the left of this note.</p>";//pop up some instructions.
        document.getElementById('userOptions').style.top=findPos(vizDiv)[1]+'px';
        document.getElementById('userOptions').style.left=(findPos(vizDiv)[0]*1+parseInt(vizDiv.style.width)+20)+'px';
        firstTypeSelect=document.getElementById("first_data_type");
        secondTypeSelect=document.getElementById("second_data_type");
        firstType=firstTypeSelect.options[firstTypeSelect.selectedIndex].text;
        secondType=secondTypeSelect.options[secondTypeSelect.selectedIndex].text;
        if(firstTypeSelect.selectedIndex==1)//checking just to make the english right when we have the units header.  still leaves "gross gross domestic production"
            firstType+=" of ";
        if(secondTypeSelect.selectedIndex==1)
            secondType+=" of ";
        document.getElementById("titleID").innerHTML="<h3 algin='left' style='text-align: center;'>"+firstType+" "+firstSelected+" ("+units[unitsFirst]+")<br/> Versus<br/> "+secondType+" "+secondSelected+" ("+units[unitsSecond]+")</h3>";
        }
        function getModString(dataType){
          switch(dataType){
            case "globalShare":
              modString="globalshare";
              break;
            case "perCapita":
              modString="pc";
              break;
            default:
              modString="";
          }
          return modString;
        }
        function handleSelection(firstFile, firstSelected, secondFile, secondSelected){
          if(!verifyForm())
            return false;
          var firstModString=getModString(document.getElementById('first_data_type').value);
          var secondModString=getModString(document.getElementById('second_data_type').value);
          var firstSet=document.getElementById("firstDataSet").value;
          var secondSet=document.getElementById("secondDataSet").value;
          var ourfriend = "alphabet";
          var firstMeans="http://cimearth.org/tools/data/"+firstSet+"/"+firstModString+"means_"+firstFile;
          var unitsFirst=firstMeans;
          var firstDevs = "http://cimearth.org/tools/data/"+firstSet+"/"+firstModString+"devs_"+firstFile;
          var secondMeans = "http://cimearth.org/tools/data/"+secondSet+"/"+secondModString+"means_"+secondFile;
          var unitsSecond = secondMeans;
          var secondDevs = "http://cimearth.org/tools/data/"+secondSet+"/"+secondModString+"devs_"+secondFile;
          var firstTotal = "http://cimearth.org/tools/data/"+firstSet+"/"+firstModString+"means_TOTAL-"+firstFile;
          var secondTotal = "http://cimearth.org/tools/data/"+secondSet+"/"+secondModString+"means_TOTAL-"+secondFile;
          var firstTotalDevs = "http://cimearth.org/tools/data/"+firstSet+"/"+firstModString+"devs_TOTAL-"+firstFile;
          var secondTotalDevs = "http://cimearth.org/tools/data/"+secondSet+"/"+secondModString+"devs_TOTAL-"+secondFile;
          var popString = "http://cimearth.org/tools/data/share_sweep/means_pop.csv";
          var totalSelectDisplayed = isVisible("total_prompt");
          var yesTotalSelected = ($("#total_prompt").val()==1);
          var totalSelected = (totalSelectDisplayed && yesTotalSelected);
          document.getElementById("visualization").innerHTML="Waiting for AJAX requests to complete";
//          $(document).ready(function(){
            $.get(popString, function(popString){//we always have population data as an option in our plot  
//              alert("???");
              $.get(firstMeans, function(firstMeans){
                $.get(secondMeans, function(secondMeans){//similarly, we always get the files at firstMeans and secondMeans.  we assume that the management of the select options is intelligent enough that we wont be looking for files that dont exist.
                /*
                we use the more complicated ajax request here (below) because it allows us to have have failure callbacks.  we dont care whether the user wants unceratinty stuff to get displayed. so, we just try and get all of the relevant files with ajax requests, and if the files we are looking for don't exist, we just say screw it and send an empty string to the draw function.  NOTE THAT I set the parameter async:false.  this is why I can use the $.ajax get requests without putting the call to drawVisualization within a callback.
                */
                  $.ajax({
                    type:"GET",
                    url:firstDevs,
                    dataType:"text",
                    async:false,
                    success:function(firstDevsGet){
                      firstDevs=firstDevsGet;
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                          //alert(XMLHttpRequest);
                          //alert(textStatus);
                          //alert(errorThrown);
                          firstDevs="";
                    }
                  });                         
                  $.ajax({
                    type:"GET",
                    url:secondDevs,
                    dataType:"text",
                    async:false,
                    success:function(secondDevsGet){
                      secondDevs=secondDevsGet;
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                          //alert(XMLHttpRequest);
                          //alert(textStatus);
                          //alert(errorThrown);
                          secondDevs="";
                    }
                  });
                  if(totalSelected){
                    $.ajax({
                      type:"GET",
                      url:firstTotal,
                      dataType:"text",
                      async:false,
                      success:function(firstTotalGet){
                        firstTotal=firstTotalGet;
                      },
                      error: function(XMLHttpRequest, textStatus, errorThrown) {
                            //alert(XMLHttpRequest);
                            //alert(textStatus);
                            //alert(errorThrown);
                            firstTotal="";
                            alert("Sorry, world total data is unavailable for this choice of data");
                      }
                    });
                    $.ajax({
                       type:"GET",
                       url:firstTotalDevs,
                       dataType:"text",
                       async:false,
                       success:function(firstTotalDevsGet){
                         firstTotalDevs=firstTotalDevsGet;  
                       },
                       error: function(XMLHttpRequest, textStatus, errorThrown) {
                            //alert(XMLHttpRequest);
                            //alert(textStatus);
                            //alert(errorThrown);
                            firstTotalDevs="";
                      }
                    });
                    $.ajax({
                       type:"GET",
                       url:secondTotal,
                       dataType:"text",
                       async:false,
                       success:function(secondTotalGet){
                         secondTotal=secondTotalGet;
                       },
                       error: function(XMLHttpRequest, textStatus, errorThrown) {
                         //alert(XMLHttpRequest);
                         //alert(textStatus);
                         //alert(errorThrown);
                         secondTotal="";
                         alert("Sorry, world total data is unavailable for this choice of data");
                      }
                    });
                    $.ajax({
                       type:"GET",
                       url:secondTotalDevs,
                       dataType:"text",
                       async:false,
                       success:function(secondTotalDevsGet){
                         secondTotalDevs=secondTotalDevsGet;
                       },
                       error: function(XMLHttpRequest, textStatus, errorThrown) {
                            //alert(XMLHttpRequest);
                            //alert(textStatus);
                            //alert(errorThrown);
                            secondTotalDevs="";
                       }
                    });
                  }
                  else{
                   firstTotal=secondTotal=firstTotalDevs=secondTotalDevs="";
                  }
                  drawVisualization(firstMeans, firstDevs, secondMeans, secondDevs, firstSelected, secondSelected, popString, unitsFirst, unitsSecond, firstTotal, secondTotal, firstTotalDevs, secondTotalDevs);
                }, "text");
              }, "text");
            }, "text");
//          });
//        return false;
        }
 


        function isVisible(id){
          var domElt=document.getElementById(id);
          if((domElt.style.visibility=="visible")&&(domElt.style.display==""))
            return true;
          else
            return false;
        }





 
        function verifyForm(){//incomplete
          var fail=0;
/*          
          if(firstFile.substr(0,4)=="void"){//i dont think this code actually does anything any more
            var typeSelect=document.getElementById("first_data_type");
            var dataType=typeSelect.options[typeSelect.selectedIndex].text;
            alert(dataType+" Data for "+firstSelected+" is unavailable");
            fail=1;
          }
          if(secondFile.substr(0,4)=="void"){//i dont think this code actually does anything any more
            var typeSelect=document.getElementById("second_data_type");
            var dataType=typeSelect.options[typeSelect.selectedIndex].text;
            alert(dataType+" Data for "+secondSelected+" is unavailable");
            fail=1;
          }*/
          first_data_type=document.getElementById('first_data_type');
          second_data_type=document.getElementById('second_data_type');
          if(first_data_type.value==""||second_data_type.value==""){
            alert("Please select between gross, global share, or per capita.");
            fail=1;
          }
          $("#firstVar option:selected").each(
            function(){
//              alert($(this).val());
              if(!($(this).hasClass($('#first_data_type').val())))
                fail=1;
              if(!($(this).hasClass($('#firstDataSet').val())))
                fail=1;
              if(fail==1)
                alert("Somethign is very wrong.");
            }
          );
          if(fail==0)
            return true;
          else
            return false;
        }
      function ShowPopup(text)
        {
            hp = document.getElementById("hoverpopup");
            par = document.getElementById("hoverparagraph");
//            if(hoveritem.selectedIndex!=0)
//              text += "  "+hoveritem.options[hoveritem.selectedIndex].text+" is Selected";
            // Set position of hover-over popup
/*            var newTop=findPos(hoveritem)[1] - 100;
            var newLeft=findPos(hoveritem)[0];
            hp.style.top = newTop+'px';
            hp.style.left = newLeft+'px';*/
            par.innerHTML=text;

            // Set popup to visible
            hp.style.visibility = "Visible";
        }

        function HidePopup()
        {
            hp = document.getElementById("hoverpopup");
            hp.style.visibility = "Hidden";
        }