// PotoSIG -- SIG extensions for Rails. Written by Javier Goizueta
// IvyGIS --- Mapserver and PostGIS on Rails.  Written by Robert S. Thau.
// Copyright 2006, Japan Spatial Information Technology, Inc.
//
// Distributed without warranty under the terms of the GNU General Public
// License, version 2.  

var PotoSvgManager = Class.create();
PotoSvgManager.prototype = {
  initialize: function (map, overlay_specs) {

    this.map = map;
    this.layer = map.create_overlay();
    this.ovl_count = 0;

    $(this.layer).style.zIndex = 8;

    map.add_listener(this);

    this.overlays = [];

    for (var i = 0; i < overlay_specs.length; ++i) 
      this.new_overlay (overlay_specs[i]);

    this.mode_detect();
    this.highlight_element = null;
  },

  new_overlay: function(overlay_spec) 
  {
    var overlay = new PotoSvgOverlay (this, overlay_spec, this.ovl_count++);

    this.overlays.push (overlay);

    if (!overlay_spec.suppress_overlay_checkbox)
      map.add_overlay (overlay_spec.map_tag, overlay);

    return overlay;
  },

  clear_all: function () {
    var layer = $(this.layer);
    var victims = [];

    for (var child = layer.firstChild; child; child = child.nextSibling)
      if (child.className == "svg_overlay_object" || child.className == "svg_overlay_progress")
        victims.push(child);

    for (var i = 0; i < victims.length; ++i)
      layer.removeChild(victims[i]);
  },
  
  hide_progress: function () {
 	var layer = $(this.layer);
    for (var child = layer.firstChild; child; child = child.nextSibling) 
		if (child.className == "svg_overlay_progress") {
			child.style.display = 'none';
		}   	
  },

  on_new_map: function () {
    this.clear_all();
  },

  on_zoom_changed: function () {
    this.clear_all(); 
  },

  on_extents_changed: function () {
  	// the progress image is not removed (it will be by the clean_handler)
	// but it is hidden if present (a new one will be diplayed, centered on-screen
	// by redisplay)
  	this.hide_progress();
    this.redisplay();
  },

  redisplay: function() {

    // If mode-detect couldn't find a way to display graphics,
    // give up immediately.

    if (this.mode == "losing") return;

    // Remember current child nodes... to be wiped away when
    // we're finished displaying the new stuff.

    var old_children = [];
    for (var elt=$(this.layer).firstChild; elt != null; elt = elt.nextSibling)
      if (elt.className == "svg_overlay_object")
        old_children.push(elt);

    // And here's the code that will do it...

   var pending_overlays = this.overlays.length;
   var hilite_element = this.highlight_element;
   var mode = this.mode

   var vp_screen = this.map.viewport_screen_coordinates();

   if (pending_overlays > 0) {
     // enable progress indicador
     var progress = document.createElement("img");
     progress.src = "/plugin_assets/potosig_engine/images/svg_progress.gif"
     progress.className  = "svg_overlay_progress";
     progress.style.position = 'relative';
	 var progress_image_size_x=50;
	 var progress_image_size_y=50;
     progress.style.left=''+((vp_screen.min_x+vp_screen.max_x)/2-progress_image_size_x)+'px';
     progress.style.top=''+((vp_screen.min_y+vp_screen.max_y)/2-progress_image_size_y)+'px';
     // progress.style.zIndex = ...; // TODO: position above existing svg layers
     $(this.layer).appendChild(progress)
   }
   
   if (mode=='svg') this.highlight_element = null;
    var cleanup_handler = function() {
      if (--pending_overlays == 0) {
	    // disable progress indicator
	    progress.parentNode.removeChild(progress);	
        for (var i = 0; i < old_children.length; ++i)
          old_children[i].parentNode.removeChild(old_children[i])
        if (hilite_element != null) {
          if (mode=='svg') {
            var p = $(hilite_element);
            if (p!=null)
              p.setAttributeNS(null,'fill','yellow');      
          }
          else if (mode=='vml') {
            // leave it to the renderer
          }
        }
      }
    };

    // Create container node...

    var container = document.createElement("div");

    container.className  = "svg_overlay_object";
    container.style.left = vp_screen.min_x + "px";
    container.style.top  = vp_screen.min_y + "px";
    container.style.width  = vp_screen.max_x - vp_screen.min_x + "px";
    container.style.height = vp_screen.max_y - vp_screen.min_y + "px";
    $(this.layer).appendChild(container);

    // If we stack SVG elements in Firefox, only the top one seems
    // to get mouse events.  So, create a "holding" SVG element for
    // them all...

    if (this.mode == "svg") {
      var svg_node = 
        document.createElementNS ("http://www.w3.org/2000/svg", "svg");

      container.appendChild(svg_node);
      container = svg_node;
    }

    // Arrange to display relevant layers...

    var map_tag = this.map.current_map_tag;
    for (var i = 0; i < this.overlays.length; ++i) {
      var overlay = this.overlays[i];
      if (overlay.map_tag == this.map.current_map_tag && overlay.active) {
        overlay.redisplay(container, cleanup_handler);
      }
      else cleanup_handler();
    }
  },
 
  mode_detect: function() {
	if (window.SVGPreserveAspectRatio && window.SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN == 2) {
      this.mode="svg"
    }
    else if (document.namespaces) {

      // Assume IE, for now...
      // Setup code cargo-culted from Emil Eklund's IeCanvas hack.

      this.mode = "vml";

      document.namespaces.add("v");


      if (false) {
        // esto no funciona con IE (pero en la demo de IvyGIS s� funciona)
      vml_obj = document.createElement('object');
      vml_obj.id = 'VMLRender';
      vml_obj.codebase = 'vgx.dll';
      vml_obj.classid = 'CLSID:10072CEC-8CC1-11D1-986E-00A0C955B42E';
      document.body.appendChild(vml_obj);

      vml_style = document.createStyleSheet();
      vml_style.addRule('v\\:*', "behavior: url(#VMLRender);");
      }
      else {
      vml_style = document.createStyleSheet();
      //vml_style.addRule('v\\:*', "behavior: url(#VMLRender);");
      vml_style.addRule('v\\:*', "behavior: url(#default#VML);");
      }      
    }
    else {
      alert ("Can't figure out how to display interactive graphics " 
             + "on your browser.  Sorry!");
      this.mode = "losing";
    }
  }
};

var PotoSvgOverlay = Class.create();
PotoSvgOverlay.prototype = {
  initialize: function (manager, spec, ovl_id)
  {
    this.manager = manager;
    this.map     = manager.map;

    this.ovl_id  = ovl_id;

    this.map_tag     = spec.map_tag;
    this.base_url    = spec.base_url;
    this.name        = spec.name;
    this.active      = spec.default_on;
    this.overlay_tag = spec.overlay_tag;
    this.compute_extra_args = spec.compute_extra_args;
    this.min_scale = spec.min_scale
    this.max_scale = spec.max_scale
  },

  set_active: function(active) {
    this.active = active;
    if (this.map_tag == this.map.current_map_tag)
      this.manager.redisplay();
  },

  redisplay: function(svg_parent, cleanup_handler) {

  // alert("max: "+this.max_scale+" scale: "+this.map.x_scale);
  

    if (this.max_scale && this.map.x_scale>this.max_scale)
      return cleanup_handler();

    if (this.min_scale && this.map.x_scale<this.min_scale)
      return cleanup_handler();

    var the_url = this.base_url + "?" + this.map.vp_form_args() +
      "&mode=" + this.manager.mode;

    if (this.compute_extra_args) {
      if (typeof(this.compute_extra_args)=='function')
        the_url += '&' + this.compute_extra_args();
      else
        the_url += '&' + this.compute_extra_args;
    }
        

    if (this.manager.highlight_element!=null && this.manager.mode=='vml') {
      the_url += '&highlight=' + this.manager.highlight_element;
      this.manager.highlight_element = null;
    }

	if (this.updater && this.updater.transport && this.updater.getStatus()==0) {
		// note that the server may still be busy and this may not bee too effective in speeding-up rendering
		this.updater.transport.abort(); // should call its cleanup handler
	}

   this.updater = new Ajax.Updater (svg_parent, the_url, 
                      {insertion: Insertion.Bottom,
                       onComplete: cleanup_handler});
  }

};
