//variable to store hidden frame
var printingHiddenFrame;

//on load, create a hidden frame for printing the map
dojo.addOnLoad(function() {
  printingHiddenFrame = document.createElement("iframe");
  printingHiddenFrame.src = "hiddenframe.html";
  dojo.style(printingHiddenFrame, "display", "none");
  dojo.body().appendChild(printingHiddenFrame);
});

//serialize the map's state and call layout.* through iframe
function printMap(m) {
  var state = {
    map: getMapState(m)
  }
  
  var iframeDocument = dojo.isIE ? printingHiddenFrame.contentWindow.document : printingHiddenFrame.contentDocument;
  iframeDocument.getElementById("appState").value = dojo.toJson(state);
  iframeDocument.getElementById("form").submit();
}

  // Print - convert a geometry to it page units complement
  function getPageGeometry(geom) {
    var pageGeom;
    var pagePath;
    var pageRing;
    
    if (geom.type == "point") {
      pageGeom = map.toScreen(geom);
      return pageGeom;
      
    } else if (geom.type == "polyline") {
      pageGeom = new esri.geometry.Polyline();
      for (p=0; p<geom.paths.length; p++) {
        pagePath = new Array();
        for (pt=0; pt<geom.paths[p].length; pt++) {
          pagePath.push(map.toScreen(new esri.geometry.Point(geom.paths[p][pt])));
        }
        pageGeom.addPath(pagePath);
      }
      return pageGeom;
    
    } else if (geom.type == "polygon") {
      pageGeom = new esri.geometry.Polygon();
      for (p=0; p<geom.rings.length; p++) {
        pagePath = new Array();
        for (pt=0; pt<geom.rings[p].length; pt++) {
          pagePath.push(map.toScreen(new esri.geometry.Point(geom.rings[p][pt])));
        }
        pageGeom.addRing(pagePath);
      }
      return pageGeom;
    
    } else {
      alert(geom.type + " Not Implemented");
      return;
    }
  }


//serialize map state into JSON, which will be transfered to the server side to generate the
//image with all the layer information and graphics information.
// {
//   extent: <Object, { xmin, ymin, xmax, ymax, spatialReference }>,
//   layers: <Object[], layer JSON>,
//   graphics: <Object[], { geometry, symbol, attributes, template }>
// }
function getMapState(m) {
  var layerStates = [], graphicsState = [], graphics = m.graphics.graphics;
  
  //serialize each layer's state
  dojo.forEach(m.layerIds, function(layerId) {
    layerStates.push( getLayerState(m.getLayer(layerId)) );
  });
  
  //serialize graphics from last to first to retain graphics drawing order
  //call getPageGeometry() to transfer geometry into screen coordinates.
  for (var i=graphics.length-1; i>=0; i--) {    
    var g = graphics[i];
    var pageGeom = getPageGeometry(g.geometry);
    var pageGraphic = new esri.Graphic(pageGeom, g.symbol);
    graphicsState.push(pageGraphic.toJson());    
  };
  
  return {
    extent: m.extent.toJson(),
    layers: layerStates,
    graphicsJson: graphicsState,
    mapWidth: m.width,
    mapHeight:m.height
  };
}

//return layer state as JSON
// {
//   id: <String>,
//   type: <String, class name>,
//   url: <String>,
//   visible: <Boolean>,
//   opacity: <Number>,
//   layerDefs: <String[], id:def>,
//   layers: <Number[]>
// }
function getLayerState(layer) {
  return {
    id: layer.id,
    type: layer.declaredClass,
    url: layer.url,
    visible: layer.visible,
    opacity: layer.opacity,
    layerDefs: layer.layerDefinitions,
    layers: layer.visibleLayers
  };
}
