dojo.require("esri.map");
dojo.require("esri.tasks.query");
dojo.require("dojox.color");
dojo.require("dojox.color.Generator");
dojo.require("dojox.gfx");

var mappedFeatureSet, colors, values, swatches;

function init() {
  //iterate and store options
  var options = document.getElementsByTagName("option");
  values = [];
  for (var i=0, il=options.length; i<il; i++) {
    values[options.item(i).innerHTML] = options.item(i).value;
  }

  //execute parser to initialize layout
  dojo.parser.parse(document.body);

  var startExtent = new esri.geometry.Extent(-83.41, 31.98, -78.47, 35.28, new esri.SpatialReference({wkid:4326}));
  //create map
  var map = new esri.Map("mapDiv",{extent:startExtent, slider:false});
  dojo.connect(map, "onLoad", initFunctionality);

  //create and add new layer
  var layer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer");
  map.addLayer(layer);
  
  //create swatches
  swatches = [];
  dojo.query(".swatch").forEach(function(swatch) {
    swatches.push(dojox.gfx.createSurface(swatch, 35, 20).createRect({x:0, y:0, width:35, height:20}).setStroke({color:[0,0,0],width:1}));
  });
  
  setColors(new dojo.Color({r:255,g:0,b:0,a:0.5}));
}

function initFunctionality(map) {
  //listen for when the map starts to pan or zoom.  If it does hide the info window.
  dojo.connect(map, "onPanStart", function() {map.infoWindow.hide()});
  dojo.connect(map, "onZoomStart", function() {map.infoWindow.hide()});
  //build query task
  var queryTask = new esri.tasks.QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/3");

  //build query filter
  var query = new esri.tasks.Query();
  query.returnGeometry = true;
  query.outFields = ["NAME", "POP2000", "POP2007", "POP00_SQMI", "POP07_SQMI", "FIPS", "MALES","FEMALES","AGE_UNDER5","AGE_5_17","AGE_18_21","AGE_22_29","AGE_30_39","AGE_40_49","AGE_50_64","AGE_65_UP","MED_AGE","MED_AGE_M","MED_AGE_F","HOUSEHOLDS","AVE_HH_SZ","HSEHLD_1_M","HSEHLD_1_F","MARHH_CHD","MARHH_NO_C","MHH_CHILD","FHH_CHILD","FAMILIES","AVE_FAM_SZ","HSE_UNITS","VACANT","OWNER_OCC","RENTER_OCC","NO_FARMS97","AVG_SIZE97","CROP_ACR97","AVG_SALE97","SQMI"];
  query.where = "STATE_NAME = 'South Carolina'";

  var infoTemplate = new esri.InfoTemplate();
  infoTemplate.setTitle("${NAME}");
  infoTemplate.setContent("${*}");
  map.infoWindow.resize(275,275);

  //Can listen for onComplete event to process results or can use the callback option in the queryTask.execute method.
  dojo.connect(queryTask, "onComplete", function(featureSet) {
    map.graphics.clear();
    mappedFeatureSet = featureSet;
    //QueryTask returns a featureSet.  Loop through features in the featureSet and add them to the map.
    for (var i=0, il=featureSet.features.length; i<il; i++) {
      //Get the current feature from the featureSet.
      //Feature is a graphic
      var graphic = featureSet.features[i];
      graphic.setInfoTemplate(infoTemplate);
      var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0,0,0,0.5]), 1),new dojo.Color(0,0,0,0));
      graphic.setSymbol(symbol);
      //Add graphic to the map graphics layer.
      map.graphics.add(graphic);
    }
    render();
  });

  queryTask.execute(query);
}

//set color range based on user color selection
function setColors(color) {
  //create color range for display
  colors = dojox.color.Generator.monochromatic({ base:color, num:6 });
  dojo.forEach(colors, function(clr, i) {
    clr.a = 0.5;
  });
  
  //feature set has been initialized, update map rendering and legend
  if (mappedFeatureSet) {
    render();
  }
}

//render legend
function render() {
  //pick field to render by from mappedField select box
  var field = values[dijit.byId("mappedField").value];
  //split by "/".  If length of array is > 1 then divide renderedField[0]/renderedField[1]
  var renderedField = field.split("/");

  //call getStats on FeatureSet for mapped field and use the min and max values to compute 6 class equal interval
  var stats = mappedFeatureSet.getStats(field);
  var interval = stats.range / 6;
  var steps = [stats.min+interval, stats.min+(interval*2), stats.min+(interval*3), stats.min+(interval*4), stats.min+(interval*5), stats.min+(interval*6)];
  
  //set approprate color for swatch
  dojo.forEach(colors, function(clr, i) {
    if (i === 0) {
      dojo.byId("lbl" + i).innerHTML = "< " + format(steps[i]);
    } else {
      dojo.byId("lbl" + i).innerHTML = format(steps[i-1]) + " - " + format(steps[i]);
    }
    swatches[i].setFill(clr);
  });

  //set symbol for each graphic based on the appropriate class value
  for (var i=0, il=mappedFeatureSet.features.length; i<il; i++) {
    var curVal=(renderedField.length > 1) ? mappedFeatureSet.features[i].attributes[renderedField[0]]/mappedFeatureSet.features[i].attributes[renderedField[1]] : mappedFeatureSet.features[i].attributes[field];
    for (var z=0; z<5; z++) {
      if (curVal <= steps[z]) {
        break;
      }
    }
    mappedFeatureSet.features[i].setSymbol(mappedFeatureSet.features[i].symbol.setColor(new dojo.Color(colors[z])));
  }
  
  esri.show(dojo.byId("legend"));
}


//Format number for displaying in legend
function format(num) {
  return Math.round(num * 100) / 100;
}

//In this example we are extending esri.tasks.FeatureSet to include a getStats method.
dojo.extend(esri.tasks.FeatureSet, {
  //This method takes a field or a field normalized by another field ("pop" or "pop"/"area").
  //It will return a stats object which has min, max, sum, and range.
  getStats: function(attribute) {
    var stats = {};
    var features = this.features;
    var renderedField = attribute.split("/");
    var maxVal = (renderedField.length > 1) ? features[0].attributes[renderedField[0]]/features[0].attributes[renderedField[1]] : features[0].attributes[attribute];
    var minVal = (renderedField.length > 1) ? features[0].attributes[renderedField[0]]/features[0].attributes[renderedField[1]] : features[0].attributes[attribute];
    var total = (renderedField.length > 1) ? features[0].attributes[renderedField[0]]/features[0].attributes[renderedField[1]] : features[0].attributes[attribute];
    for (var x = 1, xl=features.length; x < xl; x++) {
      var curVal = (renderedField.length > 1) ? features[x].attributes[renderedField[0]]/features[x].attributes[renderedField[1]] : features[x].attributes[attribute];
      maxVal = (maxVal > curVal) ? maxVal : curVal;
      minVal = (minVal < curVal) ? minVal : curVal;
      total = total + curVal;
    }
    stats.max = maxVal;
    stats.min = minVal;
    stats.sum = total;
    stats.range = maxVal - minVal;
    return stats;
  }
});

dojo.addOnLoad(init);