var Loader = {

  id: 'loading_area',

  show: function() {
    $(Loader.id).style.display = 'block';
  },

  hide: function() {
    $(Loader.id).style.display = 'none';
  }

}

var Search = {

  countId: 'count_area',
  resultId: 'result_area',
  counterId: 'counter_area',
  pagerId: 'pager_area',
  defaultId: 'default_area',
  unit: 5,
  option: '0',
  counterTpl: new LTemplate($('template_counter').value),
  resultTpl: new LTemplate($('template_search').value),
  pagerTpl: new LTemplate($('template_pager').value),
  nomatchTpl: new LTemplate($('template_nomatch').value),
  time: null,

  execute: function(q, p, o) {

    Search.time = new Date();

    if (typeof q == 'undefined') {
      if (Suggest.selected != null) {
        q = Suggest.selected[1];
        $(Suggest.inputId).value = q;
      } else {
        q = $(Suggest.inputId).value;
      }
    }
    $(Search.resultId).innerHTML = '';

    if (typeof p == 'undefined') {
      p = 0;
    }

    if (typeof o != 'undefined') {
      Search.option = o;
    } else if ($('search_option_0').checked) {
      Search.option = '0';
    } else if ($('search_option_1').checked) {
      Search.option = '1';
    } else if ($('search_option_2').checked) {
      Search.option = '2';
    }

    new Ajax.Request("search.php", {
      method: "post", asynchronous: true, parameters: 'p=' + encodeURIComponent(p)
        + '&q=' + encodeURIComponent(q) + '&o=' + encodeURIComponent(Search.option),
      onComplete: Search.show
    });

    Search.loading();
    Suggest.now = $(Suggest.inputId).value;
    Suggest.hide();
  },

  show: function(request) {

    var json = eval(request.responseText);
    var count = parseInt(json['count']);
    var countFormat = json['count_format'];
    var start = parseInt(json['start']);
    var end = start + Search.unit > count ? count : start + Search.unit;
    var query = json['query'];
    var matches = json['matches'];
    var time = Math.round((new Date() - Search.time) / 10) / 100; 

    Loader.hide();

    if (count != null && count > 0) {

      Maps.move(matches[0]['kanji']);

      $(Search.counterId).innerHTML = Search.counterTpl.applyTemplate(
        {'time':time, 'countFormat':countFormat, 'start':start, 'end':end}
      );

      $(Search.resultId).innerHTML = Search.resultTpl.applyTemplate(matches);
      $(Search.resultId).style.display = 'block';

      if (count > 5) {
        $(Search.pagerId).innerHTML = Search.pagerTpl.applyTemplate(
          {'count':count, 'start':start, 'query':query}
        );
        $(Search.pagerId).style.display = 'block';
      } else {
        $(Search.pagerId).style.display = 'none';
      }

      Maps.clearMark();
      for (var i = 0, len = matches.length; i < len; i++) {
        Maps.addMark(matches[i]['kanji']);
      }

    } else {
 
      $(Search.resultId).innerHTML = Search.nomatchTpl.applyTemplate({});
      $(Search.resultId).style.display = 'block';
      Maps.clearMark();
      Maps.reset();
 
    }
  },

  loading: function() {
    $(Search.defaultId).style.display = 'none';
    $(Search.resultId).style.display = 'none';
    $(Search.pagerId).style.display = 'none';
    Loader.show();
  }

}

var Suggest =  {

  inputId: 'input',
  templateId: 'template_suggest',
  resultId: 'suggest_area',
  lineId: 'suggest_line_',
  selected: null,
  now: '',

  start: function() {
    Suggest.now = $(Suggest.inputId).value;
    Suggest.watch();
  },

  watch: function() {
    var q = $(Suggest.inputId).value;
    if (Suggest.now != q) {
      Suggest.now = q;
      Suggest.execute(q);
    }
    setTimeout(Suggest.watch, 500);
  },

  execute: function(q) {
    new Ajax.Request("suggest.php", {
      method: "post", asynchronous: true, parameters: 'q=' + encodeURIComponent(q),
      onComplete: Suggest.show
    });
  },

  show: function(request) {
    var json = eval("(" + request.responseText + ")");
    if (json != null && json[1] != null) {
      var suggestList = json[1];
      if (suggestList.length == null || suggestList.length == 0) {
        Suggest.hide();
      } else {
        var tpl = new LTemplate($(Suggest.templateId).value);
        $(Suggest.resultId).innerHTML = tpl.applyTemplate(suggestList);
        $(Suggest.resultId).style.display = 'block';
      }
    } else {
      Suggest.hide();
    }
  },

  hide: function() {
    Suggest.selected = null;
    $(Suggest.resultId).innerHTML = '';
    $(Suggest.resultId).style.display = 'none';
  },

  search: function(query) {
    $(Suggest.inputId).value = query;
    Suggest.now = $(Suggest.inputId).value;
    Search.execute(query);
  },

  select: function(id) {
    var all = $(Suggest.resultId).getElementsByTagName('div');
    var isSelect = false;
    for (var i = 0, len = all.length; i < len; i++) {
      if (all[i].id == id) {
        Suggest.setSelected(id, all[i].innerHTML);
        all[i].className = 'suggest_line suggest_selected';
        isSelect = true;
      } else {
        all[i].className = 'suggest_line';
      }
    }
    if (!isSelect) {
      Suggest.selected = null;
    }
  },

  selectByKey: function(keyCode) {
    if (keyCode == 27) {  // ESC
      Suggest.hide();
    } else if (keyCode == 38 || keyCode == 40) { // UP, DOWN
      var flg = keyCode == 38 ? -1 : 1;
      var all = $(Suggest.resultId).getElementsByTagName('div');
      var targetId = '';
      if (Suggest.selected == null) {
        targetId = 0;
      } else {
        targetId = Suggest.selected[0] + flg;
      }
      if (all != null && all.length != 0 && targetId < all.length) {
        Suggest.select(Suggest.lineId + targetId);
      }
    } else if (keyCode == 13 && Suggest.selected != null) {
      $(Suggest.inputId).value = Suggest.selected[1];
    }
  },

  setSelected: function(id, value) {
    Suggest.selected = [parseInt(id.replace(Suggest.lineId, '')), value];
  }

}

var Maps = {

  id: 'maps_area',
  map: null,
  defaultZoom: 4,
  searchZoom: 15,

  show: function() {
    if (GBrowserIsCompatible()) {
      Maps.map = new GMap2($(Maps.id));
      Maps.map.addControl(new GSmallMapControl());
      Maps.map.setCenter(new GLatLng(38, 137), Maps.defaultZoom);
    }
  },

  reset: function() {
    Maps.map.setCenter(new GLatLng(38, 137), Maps.defaultZoom);
  },

  move: function(address) {
    address = address.replace('以下に掲載がない場合', '');
    var geocoder = new GClientGeocoder();
    geocoder.getLocations(address, function(locations) {
      if (locations && locations.Placemark && locations.Placemark.length > 0) {
        Maps.map.setZoom(Maps.searchZoom);
        var coordinates = locations.Placemark[0].Point.coordinates;
        var latlng = new GLatLng(coordinates[1], coordinates[0]);
        Maps.map.panTo(latlng);
      }
    });
  },

  addMark: function(address) {
    var geocoder = new GClientGeocoder();
    geocoder.getLocations(address, function(locations) {
      if (locations && locations.Placemark && locations.Placemark.length > 0) {
        var coordinates = locations.Placemark[0].Point.coordinates;
        var latlng = new GLatLng(coordinates[1], coordinates[0]);
        var marker = new GMarker(latlng);
        Maps.map.addOverlay(marker);
        GEvent.addListener(marker, 'click', function() {
          marker.openInfoWindowHtml('<p class="marker_window">' + address + '</p>');
        });
      }
    });
  },

  clearMark: function() {
    Maps.map.clearOverlays();
  }

}

Event.observe(window.document, 'keydown', function(e) {
  Suggest.selectByKey(e.keyCode);
}, false);
Event.observe(document.getElementsByTagName('html')[0], 'click', function(e) {
  Suggest.hide();
}, false);
Event.observe(window, 'load', function(e) { Suggest.start() }, false);
Maps.show();
$(Suggest.inputId).focus();
