var Map = Class.create();
Map.prototype= {

  initialize: function(element, options) {
    this.options = Object.extend({
      script: '/map/search.php',
      point : new GLatLng(35.009998, 135.75),
      zoom  : 12
    }, options || {});

    this.icon = new GIcon();
    this.icon.image      = 'image/icon01.png';
    this.icon.iconSize   = new GSize(30, 40);
    this.icon.iconAnchor = new GPoint(15, 40);
    this.icon.shadow     = 'image/shadow.png';
    this.icon.shadowSize = new GSize(50, 40);
    this.icon.infoWindowAnchor = new GPoint(15, 0);

    this.images = {
      '社寺'        : 'image/icon02.png',
      '公衆トイレ'  : 'image/icon03.png',
      '多目的トイレ': 'image/icon04.png',
      '体験施設'    : 'image/icon05.png'
    }

    this.template = new Template('\
<div class="window">\
  <h3>#{title}</h3>\
  <p class="clear">#{address}<br />\
    #{comment}［<a onclick="window.opener.location.href = this.href; window.opener.focus(); return false" href="../#{script}?lid=#{lid}">#{string}</a>］</p>\
</div>\
');

    this.map = new GMap2($(element));
    this.map.setCenter(this.options.point, this.options.zoom);
    this.map.addControl(new GLargeMapControl());
    this.map.addControl(new GMapTypeControl());
    this.map.addControl(new GOverviewMapControl());
    this.map.addControl(new GScaleControl());

    GEvent.addListener(this.map, 'dragend', this.request.bind(this));
    GEvent.addListener(this.map, 'zoomend', this.request.bind(this));

    $$('#category label').each(function(element) {
      Event.observe(element, 'click', function() {
        if (!element.down().checked)
          element.down().checked = true;
        this.request();
      }.bind(this));
    }.bind(this));

    $$('#menu input[type!="text"]', 'button').each(function(element) {
      if (element.name == 'bound' && location.search.toQueryParams().lid)
        element.checked = false;

      Event.observe(element, 'click', function() {
        this.request();
      }.bind(this));
    }.bind(this));

    this.printable = false;

    Event.observe($$('#print_menu a').last(), 'click', function(event) {
      if (this.printable) this.print();
      Event.stop(event);
    }.bind(this));

    this.request();
  },

  request: function(params) {
    if (!this.params || !this.params.lid) {
      this.printable = false;
      $$('#print_menu a').last().removeClassName('active');
    }

    params = Object.extend(Form.serialize('menu').toQueryParams(), params || {});

    $$('#menu input[type="checkbox"]').each(function(element) {
      params[element.name] = element.checked;
    });
    this.toggleClass();

    if (params.bound)
      Object.extend(params, {
        n: this.map.getBounds().getNorthEast().lat(),
        e: this.map.getBounds().getNorthEast().lng(),
        s: this.map.getBounds().getSouthWest().lat(),
        w: this.map.getBounds().getSouthWest().lng()
      });

    if (!params.bound && !params.page && this.params)
      params.page = this.params.page;

    if (!params.bound && location.search.toQueryParams().lid)
      params = { lid: location.search.toQueryParams().lid }

    this.params = $H();

    $H(params).values().each(function(value, index) {
      if (value)
        this.params[$H(params).keys()[index]] = value;
    }.bind(this));

    if (this.histry && this.histry == this.params.toQueryString()) return;

    new Ajax.Request(this.options.script, {
      method    : 'get',
      onSuccess : this.response.bind(this),
      parameters: this.params.toQueryString()
    });
    this.histry = this.params.toQueryString();
  },

  response: function(response) {
    response = eval('(' + response.responseText + ')');

    $('result').innerHTML = '&nbsp;' + response.status.pagenumber;
    $('hidden').innerHTML = '';

    $$('#result a').each(function(element) {
      Event.observe(element, 'click', function(event) {
        this.request(element.href.toQueryParams());
        Event.stop(event);
      }.bind(this));
    }.bind(this));

    this.map.clearOverlays();

// 印刷用
    var elements = '';
    var template = new Template('\
<tr class="#{class}">\
  <td class="number"><img src="image/print_number#{number}.gif" alt="#{number}" /></td>\
  <th>#{title}</th>\
  <td>#{address}</td>\
');
    response.institutions.each(function(value, index) {
      if (!value) return;
      elements += template.evaluate(Object.extend({
        'class': index % 2 ? '' : 'colored',
        'number': (index < 9 ? '0' : '') + (index + 1)
      }, value || {}));
    });
    $('print').update('<table>' + elements + '</table>');
    this.printable = true;
    $$('#print_menu a').last().addClassName('active');

    response.institutions.each(function(value, index) {
      this.createMarker(value, index);
    }.bind(this));
  },

  createMarker: function(institution, index) {
    var icon = this.icon;

    $w(institution.category).each(function(value) {
      if (this.images[value]) icon.image = this.images[value];
    }.bind(this));

    icon.mozPrintImage = 'image/print_icon' + (index < 9 ? '0' : '') + (index + 1) + '.gif';
    icon.printImage    = 'image/print_icon' + (index < 9 ? '0' : '') + (index + 1) + '.gif';

    var marker = new GMarker(new GLatLng(institution.lat, institution.lng), { icon: icon });
    $('hidden').innerHTML += institution.comment;

    GEvent.addListener(marker, 'click', function() {
      marker.openInfoWindowHtml(this.template.evaluate(Object.extend({
        script: institution.genre == 'institutions' ? 'experience/list.php' : 'walk/detail.php',
        string: institution.genre == 'institutions' ? 'この施設の体験学習を見る' : '詳細を見る'
      }, institution || {})));
    }.bind(this));

    this.map.addOverlay(marker);

    if (this.params.lid)
      this.map.setCenter(marker.getPoint(), 15);
  },

  toggleClass: function() {
    $$('#category input').each(function(element) {
      element.up().removeClassName('active');
      if (element.checked)
        element.up().addClassName('active');
    });
  },

  print: function() {
    window.print();
  }

}