var Map = new Class ({
  Implements : Options,
  options : {
      'form': undefined
    ,'ajaxRequestHash':{}
    ,'ajaxRequestUrl' :undefined
    ,'ajaxReplaceId'  :undefined
  },
  initialize: function(element, options){
    this.setOptions(options);
    this.options = $merge(this.options, (JSON.decode($('map_options').get('text'))));
    this.map = element;
    this.map.addEvent('mouseover', this.mouseOver.bindWithEvent(this));
    this.map.addEvent('mouseout', this.mouseOut.bind(this));
    this.map.addEvent('click', this.selectPoint.bindWithEvent(this));
    this.map.addEvent('mousewheel', this.mouseScroll.bindWithEvent(this));
    this.map.position = this.map.getPosition();
    window.addEvent('resize', this.resize.bindWithEvent(this));
    
    this.crosshair = $('crosshair');
    this.crosshair.offset = this.crosshair.getStyle('width').toInt()/2;
    this.crosshair.position = this.crosshair.getPosition()
    this.crosshair.position.x -= this.map.position.x;
    this.crosshair.position.y -= this.map.position.y;
    this.crosshairVisibility = this.crosshair.getStyle('display');
    if(Browser.Engine.trident)
    {
      var image = this.crosshair.getStyle('background-image');
      this.crosshair.setStyles({'background-image':'none'
      ,'filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+site_base+"/resources/images/layout/crosshair30.png', sizingMethod='scale')"});
    }
    
    
    this.brancheSelect = $('brancheselect');
    this.brancheSelect.addEvent('change', this.brancheChanged.bind(this))
    this.searchField = $('searchfield');
    if(this.searchField.value == ''){this.searchField.value = 'trefwoorden';this.searchField.setStyle('color','#aaa');}
    this.searchField.addEvent('focus', function(e) {
      if(this.searchField.value == 'trefwoorden')
      {
        this.searchField.value = '';
        this.searchField.setStyle('color','#000');
      }
    }.bind(this));
    this.searchField.addEvent('blur', function(e) {
      if(this.searchField.value == '')
      {
        this.searchField.value = 'trefwoorden';
        this.searchField.setStyle('color','#aaa');
      }
    }.bind(this));

    
    
    
    this.zipcode = $('zipcode');
    if(this.zipcode.value == ''){this.zipcode.value = 'postcode';this.zipcode.setStyle('color','#aaa');}
    this.zipcode.addEvent('change', this.zipcodeChanged.bind(this));
    this.zipcode.addEvent('focus', function(e) {
      if(this.zipcode.value == 'postcode')
      {
        this.zipcode.value = '';
        this.zipcode.setStyle('color','#000');
      }
    }.bind(this));
    this.zipcode.addEvent('blur', function(e) {
      if(this.zipcode.value == '')
      {
        this.zipcode.value = 'postcode';
        this.zipcode.setStyle('color','#aaa');
      }
    }.bind(this));
    
    this.rangeSelect = $('rangeselect');
    this.rangeSelect.addEvent('change', this.rangeChanged.bind(this));
    
    $('gobutton').addEvent('click', this.submitForm.bindWithEvent(this));

    this.changeCrosshair.bind(this);
    this.changeCrosshair();
    this.addMoreAction($(this.options.ajaxReplaceId));
    var requestOptions = {
        'url':this.options.ajaxRequestUrl
      , 'method':'post'
    }
    this.pageRequest = new Request(requestOptions);
    this.pageRequest.onSuccess = this.processAjaxRequest.bind(this);
  },
  resize : function(event) {
    this.map.position = this.map.getPosition();
  },  
  mouseOver: function(event) {
    this.crosshair.setStyles({'display':'block'
                             ,'left': event.page.x-this.map.position.x-this.crosshair.offset
                             ,'top' : event.page.y-this.map.position.y-this.crosshair.offset});
    this.map.addEvent('mousemove', this.mouseMove.bindWithEvent(this));
  },
  mouseOut: function(event) {
    this.crosshair.setStyles({'display':this.crosshairVisibility,'left':this.crosshair.position.x, 'top':this.crosshair.position.y});
    this.map.removeEvent('mousemove');
  },
  mouseMove: function(event) {
    var xPos = event.page.x-this.map.position.x-this.crosshair.offset;
    var yPos = event.page.y-this.map.position.y-this.crosshair.offset;
    this.crosshair.setStyles({'left':xPos, 'top':yPos});
  },
  mouseScroll: function(event) {
    event = new Event(event);
    event.stop();
    index = this.rangeSelect.selectedIndex;
    if(event.wheel > 0)
    {
      newIndex = index == 0 ? 0 : index-1;
      this.rangeSelect.selectedIndex = newIndex;
    }
    if(event.wheel < 0)
    {
      newIndex = index >= 3 ? 3 : index+1;
      this.rangeSelect.selectedIndex = newIndex;      
    }
    if(index != newIndex)
    {
      this.rangeChanged();
      if(this.crosshairVisibility == 'none') {
        this.mouseMove(event);
        this.crosshair.setStyle('display','block');
      }
    }
  },
  selectPoint: function(event) {
    new Event(event).stop();
    var xPos = event.page.x-this.map.position.x;
    var yPos = event.page.y-this.map.position.y;
    this.crosshair.position.x = xPos-this.crosshair.offset;
    this.crosshair.position.y = yPos-this.crosshair.offset;
    this.crosshairVisibility = 'block';
    this.crosshair.setStyles({'left':this.crosshair.position.x,'top':this.crosshair.position.y});
    
    this.doAjaxRequest({'map_x':xPos, 'map_y':yPos});
  },
  doAjaxRequest: function(options) {
    var defaults = {'range':this.rangeSelect.value
                   ,'branche':this.brancheSelect.value
                   ,'keywords':this.searchField.value=='trefwoorden'? '':this.searchField.value
    }
    var requestHash = $H(this.options.ajaxRequestHash);
    requestHash.extend(defaults);
    requestHash.extend(options)
    this.pageRequest.send(requestHash.toQueryString());
  },
  processAjaxRequest: function(responseText, responseXML)
  {
    var oldElement = $(this.options.ajaxReplaceId);
    var newElement = new Element('div',{id:this.options.ajaxReplaceId});
    
    var response = JSON.decode(responseText);
    if(response.zipcode!=null)
    {
      this.zipcode.value = response.zipcode;
    }
    if(response.x != null && response.y != null)
    {
      this.crosshairVisibility = 'block';
      this.crosshair.position.x = response.x-this.crosshair.offset
      this.crosshair.position.y = response.y-this.crosshair.offset
      
    }
    else
    {
      this.crosshairVisibility = 'none';
    }
    this.changeCrosshair();
    newElement.set('html', response.html);
    this.addMoreAction(newElement);
    
    replace = new Fx.Replace(newElement, {'replaceId':this.options.ajaxReplaceId});
    replace.start();
  },
  rangeChanged: function() {
    this.changeCrosshair();
    var zipcode = this.zipcode.value.trim();
    if(this.crosshairVisibility != 'none') {
        this.doAjaxRequest({'map_x':this.crosshair.position.x+this.crosshair.offset
                           ,'map_y':this.crosshair.position.y+this.crosshair.offset});}
    else if(zipcode != '' && zipcode != 'postcode') {
      this.doAjaxRequest({'zipcode':this.zipcode.value});}
  },
  changeCrosshair: function() {
    var range = this.rangeSelect.value;
    var width = this.options.rangeSizes[range];
    var oldOffset = this.crosshair.offset;
    this.crosshair.offset = width/2;
    this.crosshair.position.x -= this.crosshair.offset-oldOffset;
    this.crosshair.position.y -= this.crosshair.offset-oldOffset;
    
    this.crosshair.setStyles({'background-image':'url('+site_base+'/resources/images/layout/crosshair'+range+'.png)'
                             ,'width':width
                             ,'height':width
                             ,'left':this.crosshair.position.x
                             ,'top':this.crosshair.position.y
                             ,'display':this.crosshairVisibility});
    if(Browser.Engine.trident)
    {
      this.crosshair.setStyles({'background-image':'none'
      , 'filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+site_base+"/resources/images/layout/crosshair"+range+".png', sizingMethod='scale')"});
    }

  },
  brancheChanged: function() {
    this.updateMap();
    var zipcode = this.zipcode.value.trim();
    if(this.crosshairVisibility != 'none') {
        this.doAjaxRequest({'map_x':this.crosshair.position.x+this.crosshair.offset
                           ,'map_y':this.crosshair.position.y+this.crosshair.offset});}
    else if(zipcode != '' && zipcode != 'postcode') {
      this.doAjaxRequest({'zipcode':this.zipcode.value});}
    else {
      this.doAjaxRequest({});
    }
  },
  updateMap: function() {
    $('map_overlay').set('src',site_base+'/resources/scripts/overlay.php?branche='+this.brancheSelect.value+'&keywords='+(this.searchField.value=='trefwoorden'?'':this.searchField.value));
  },
  zipcodeChanged: function() {
    if(this.zipcode.value.length >= 4){
      this.doAjaxRequest({'zipcode':this.zipcode.value});
    }
  },
  submitForm: function(e) {
    new Event(e).stop();
    this.updateMap();
    var zipcode = this.zipcode.value.trim();
    if(this.crosshairVisibility != 'none') {
        this.doAjaxRequest({'map_x':this.crosshair.position.x+this.crosshair.offset
                           ,'map_y':this.crosshair.position.y+this.crosshair.offset});}
    else if(zipcode != '' && zipcode != 'postcode') {
      this.doAjaxRequest({'zipcode':this.zipcode.value});}
    else {
      this.doAjaxRequest({});
    }
  },
  addMoreAction: function(companies)
  {
    companies.getElements('.company').each(function (company) {
      var more = company.getElement('.more');
      if(more != undefined)
      {
        var extra   = company.getElement('.extra');
        var dots    = company.getElement('.dots');
        var descr   = company.getElement('.descr');
        extra.addClass('hidden');
        dots.removeClass('hidden');
        more.store('extra', extra)
        more.store('dots', dots);
        more.store('descr', descr);
        more.addEvent('click', this.moreClickEvent.bindWithEvent(this, more));
      }
    }, this);
  },
  moreClickEvent: function(event, more) {
    new Event(event).stop();
    var descr = more.retrieve('descr');
    var effect = more.retrieve('effect', new Fx.Tween(descr, 'height', {duration:200}));
    var height = more.retrieve('height', descr.getHeight());
    if(more.retrieve('open', false))
    {
      more.setStyle('background-image','url('+site_base+'/resources/images/layout/boxed_plus.gif)');
      var scrollHeight = more.retrieve('scrollHeight', descr.getScrollHeight());
      effect.start('height', scrollHeight, height).chain(function () {
        more.retrieve('dots').removeClass('hidden');
        more.retrieve('extra').addClass('hidden');        
      });
      more.store('open', false);
    }
    else
    {
      more.setStyle('background-image','url('+site_base+'/resources/images/layout/boxed_min.gif)');
      descr.setStyle('height', height);
      more.retrieve('extra').removeClass('hidden'); 
      more.retrieve('dots').addClass('hidden');
      var scrollHeight = more.retrieve('scrollHeight', descr.getScrollHeight());
      effect.start('height', height, scrollHeight);
      more.store('open', true);
    }
  }
})
