/*
 * GPort requires {name:<port of>,latlng:<GLatLng()>,zoom:<zoom>)
 */
function GChart(opts) { 
  this.chart_id = null;
  this.title = null;
  this.panels = [];
  this.isHidden = false;
  this.initialize(opts);
};


GChart.prototype.hide = function() { 
  this.isHidden = true;
  for(var i in this.panels) { 
    this.panels[i].hide();
  }
};

GChart.prototype.show = function() { 
  this.isHidden = false;
  for(var i in this.panels) { 
    this.panels[i].show();
  }
};


GChart.fromDom = function(dom,opts) { 
  opts = (!opts) ? {} : opts;
  var titles = dom.getElementsByTagName("title");
  if( titles.length < 1 ) { 
    return false;
  }
  opts['title']    = titles[0].firstChild.nodeValue;
  opts['chart_id'] = dom.getAttribute("chart_id");

  opts['panels'] = [];
  var panelz = dom.getElementsByTagName("panel");
  for(var i=0,n=panelz.length; i<n; i++) { 
    opts['panels'].push(GPanel.fromDom(panelz[i]));
  }

  return new GChart(opts);
};
 

GChart.prototype.escapeEntities = function(str) { 
  str = String(str).replace(/'/, "&apos;");
  str = String(str).replace(/"/, "&quot;");
  str = String(str).replace(/</, "&lt;");
  str = String(str).replace(/>/, "&rt;");
  str = String(str).replace(/&/, "&amp;");
  return str;
};


GChart.prototype.toString = function() { 
  var tip = String(this.title).replace(/;/,"; ");
  tip = this.escapeEntities(tip);
  tip = tip.replace(/Ent\.?(\s+)/i, "Entrance\1");
  tip = tip.replace(/Pt\.?(\s+)/i, "Point\1");
  tip = tip.replace(/Str\.?(\s+)/i, "Strait\1");

  return '<span title="'+tip+'">'+
    this.chart_id+' - '+this.title+'</span>';
};


GChart.prototype.getBounds = function() { 
  if( this.panels.length < 1 ) { 
    return null;
  }

  var bbox = new GLatLngBounds();
  for(var i=0,n=this.panels.length; i<n; i++) { 
    var bb = this.panels[i].getBounds();
    var sw = bb.getSouthWest();
    var ne = bb.getNorthEast();
    bbox.extend(ne); // top-right
    bbox.extend(new GLatLng(ne.lat(),sw.lng())); // top-left
    bbox.extend(new GLatLng(sw.lat(),ne.lng())); // bottom-right
    bbox.extend(sw);  // bottom-left
  }
  return bbox;
};


GChart.prototype.getPolygons = function() { 
  var polygons = [];
  for(var i in this.panels) { 
    if( this.panels[i].polygon instanceof GPolygon ) { 
      polygons.push(this.panels[i].polygon);
    }
  }
  return polygons;
};


GChart.prototype.initialize = function(opts) { 
  for(var i in opts) { 
    this[i] = opts[i];
  }
  for(var i in this.panels) { 
    this.panels[i].parent = this;
  }

  // Assign title(s) to panel(s)
  var titles = this.title.split(";");

  if( titles.length == this.panels.length ) { 
    // panels split on semi-colon match panel count
    for(var i in titles) { 
      this.panels[i].title = titles[i];
    }
  } else { 
    // else: assign parent title to each child
    for(var i in this.panels) { 
      this.panels[i].title = this.title;
    }
  }
};




function GPanel(opts) { 
  this.file_name = null;
  this.panel_no  = null;
  this.title     = null;
  this.scale     = null;
  this.polygon   = null;
  this.isHidden  = false;
  this.initialize(opts);
};

GPanel.prototype.initialize = function(opts) { 
  for(var i in opts) { 
    this[i] = opts[i];
  }

  if( !this.title ) { 
    this.title = this.file_name;
  }
  if( !this.title ) { 
    this.title = this.panel_no;
  }
  if( this.polygon ) { 
    this.polygon.title = this.title;
  }
};


GPanel.fromDom = function(dom,opts) { 
  opts = (!opts) ? {} : opts;
  
  opts['file_name'] = dom.getAttribute("file_name");
  opts['panel_no']  = dom.getAttribute("panel_no");
  opts['scale']     = dom.getAttribute("scale");
  var enc_poly = {
    'numLevels':18,
    'zoomFactor':2,
    'points':dom.getAttribute("encoded_polygon"),
    'levels':dom.getAttribute("encoded_levels"),
    'opacity':0.5,
    'weight':2,
    'color':'#f33'
  };
  opts['polygon'] = GPolygon.fromEncoded({
    'polylines':[enc_poly],
    'color':'#333',
    'opacity':0.1,
    'fill':true,
    'outline':true
  });

  return new GPanel(opts);
};


GPanel.prototype.hide = function() { 
  this.isHidden = true;
};

GPanel.prototype.show = function() { 
  this.isHidden = false;
};

GPanel.prototype.getPolygon = function() { 
  return this.polygon;
};

GPanel.prototype.getBounds = function() { 
  return this.polygon.getBounds();
};

GPanel.prototype.getArea = function() { 
  return this.polygon.getArea();
};



/*
 * GChartControl implements interface GControl()
 */
function GChartControl(printable,selectable) { 
  GListControl.call(this,printable,selectable);

  this.setOptionLength(15);
  this.setWidth('240px');
  this.setDefaultTitle('Chart ...','Jump to RNC Nautical Chart');
  this.overlays = [];
  this.loaded = false;
  this.showPolygons = true;
  this.showEffects  = false;

  var me = this;
  GEvent.addListener(me,"itemselected",function(idx) {
    if( typeof(me.items[idx]) != "undefined" ){ 
      var zoom = me.map.getBoundsZoomLevel(me.items[idx].getBounds());
      me.map.setCenter(me.items[idx].getBounds().getCenter(),zoom);
    }

    // remove previous overlays
    for(var i in me.overlays) { 
      if( me.overlays[i].visible ) { 
        me.overlays[i].visible = false;
        GEvent.clearInstanceListeners(me.overlays[i]);
        me.map.removeOverlay(me.overlays[i]);
      }
    }
    me.overlays = [];

    if( !me.showPolygons ) { 
      return;
    }

    // add new overlays
    me.overlays = me.items[idx].getPolygons();
    for(var i in me.overlays) { 
      me.overlays[i].visible = false;
      if( me.showEffects ) { 
        GEvent.addListener(me.overlays[i],'mouseover',function() { 
          this.setStrokeStyle({'color':'#555','opacity':0.8,'weight':2});
          this.setFillStyle({'color':'#f33','opacity':0.1});
          // polygon.fill = true;
        });

        GEvent.addListener(me.overlays[i],'mouseout',function() { 
          this.setStrokeStyle({'color':'#33f','opacity':0.5,'weight':2});
          this.setFillStyle({'color':'#333','opacity':0.1});
          // polygon.fill = true;
        });
      } // if( me.showEffects )
      me.map.addOverlay(me.overlays[i]);
      me.overlays[i].visible = true;
    } // for(var i in me.overlays)


    window.setTimeout(function() { 
      // remove previous overlays
      for(var i in me.overlays) {
        if( me.overlays[i].visible ) {
          me.overlays[i].visible = false;
          GEvent.clearInstanceListeners(me.overlays[i]);
          me.map.removeOverlay(me.overlays[i]);
        }
      }
    }, 2500); 

  });  // GEvent.addListener(me,"itemselected",function(idx));
}
// Extends GControl()
GChartControl.prototype = new GListControl();



// interface GControl()
GChartControl.prototype.getDefaultPosition = function() { 
  return new GControlPosition(G_ANCHOR_TOP_RIGHT,new GSize(270,7))
};


GChartControl.prototype.isLoaded = function() { 
  return this.loaded;
};

GChartControl.prototype.sort = function() { 
  return this.items.sort(function(a,b) {
    return (parseInt(a['chart_id'],10) > parseInt(b['chart_id'],10)) ? 1 : -1;
  });
};


GChartControl.prototype.show = function(bounds) { 
  for(var i in this.items) { 
    var ch = this.items[i];
    ch.hide();
    for(var j in ch.panels) { 
      var pa = ch.panels[j];
      if( pa.getBounds().intersects(bounds) ) { 
        ch.show();
        break;
      }
    }
  }
  this.redraw();
};



GChartControl.prototype.load = function() { 
  var LC = this;
  var url = 'xml/rncs.xml';
  LC.loaded = false;

  this.getTitleContainer().innerHTML = "Loading...";
  GDownloadUrl(url,function(data,code) { 
    if( code != 200 ) { 
      LC.loaded = true;
      GEvent.trigger(LC,"load",data,code);
      return false;
    }

    LC.reset();
    var dom = GXml.parse(data);

    var charts = dom.getElementsByTagName("chart");
    for(var i=0,n=charts.length; i<n; i++) { 
      LC.add(GChart.fromDom(charts[i],{'isHidden':true}));
    }

    LC.sort();
    LC.redraw();
    LC.loaded = true;
    GEvent.trigger(LC,"load",data,code);
  });
};


GChartControl.prototype.listContainsLatLng = function(latlng) { 
  var rlist = [];
  for(var i in this.items) { 
    for(var j in this.items[i].panels) { 
      if( this.items[i].panels[j].getBounds().containsLatLng(latlng) ) { 
        rlist.push(this.items[i].panels[j]);
      }
    }
  }
  rlist.sort(function(a,b) { return (a.scale-b.scale); });
  return rlist;
};



GChartControl.prototype.getPanelById = function(id) { 
  for(var i in this.items) { 
    for(var j in this.items[i].panels) { 
      if( String(this.items[i].panels[j].file_name).indexOf(id)>=0 ) { 
        return this.items[i].panels[j];
      }
    }
  }
  return null;
};

