/**
 * GSliderControl class
 * Copyright (c) 2007, Viktor Szule, viktor.szule@gmail.com
 *
 * Version: 0.62
 *
 * Tested widh: 
 *      - Internet Explorer 7
 *      - Internet Explorer 6
 *      - Netscape 9.0b1
 *      - FireFox 2.0.0.4
 *      - Opera 9.21
 *      - Safari 3.0.2
 *
 * Limitations:
 *      - Opacity is not working correctly with Internet Explore 6 or older versions
 */

/** 
 * Constructor for GSliderControl
 * @param {opts_controlParams} Named optional arguments:
 *   opts_controlParams.x {Number} x position of control
 *   opts_controlParams.y {Number} y position of control
 *   opts_controlParams.opacity {Number} opacity of control
 *   opts_controlParams.pointerOpacity {Number} opacity of slider pointers
 *   opts_controlParams.enableSliderPointers {Boolean} enable or disable slider pointers
 * @param {opts_zoomBoxParams} Named optional arguments:
 *   opts_zoomBoxParams.fillColor {String} x fill color of zoomBox
 *   opts_zoomBoxParams.borderColor {String} border color of zoomBox
 *   opts_zoomBoxParams.opacity {Number} opacity of control
 *   opts_zoomBoxParams.borderWidth {Number} border width in pixel
 *   opts_zoomBoxParams.enabled {Boolean} enable or disable the control
 */
 
function GSliderControl(opts_controlParams, opts_zoomBoxParams) { 
  this.controlParams = { 
    x: 17,
    y: 17,
    opacity: 1,
    pointerOpacity: 1,
    enableSliderPointers: true
  };
  
  for (var s in opts_controlParams) {
    this.controlParams[s] = opts_controlParams[s];
  }
  
  var opacity = opts_controlParams.opacity;
  if (getBrowserType_() == 5) opacity = 1;
  
  this.zoomBoxParams = {
    fillColor: '#8888BB',
    borderColor: '#4444BB',
    opacity: .3,
    borderWidth: 2,
    enabled: true
  };
  
  for (var s in opts_zoomBoxParams) {
    this.zoomBoxParams[s] = opts_zoomBoxParams[s];
  }
  
  this.globals = {
    maxZoom: 17
  };
};

/**
 * Declare GSliderControl
 */
GSliderControl.prototype = new GControl();

GSliderControl.prototype.setSlider_ = function(zoom) {
  var 
    top = this.getKnobTop_(zoom),
    t = parseInt(this.knob.style.top);
  this.slide.top = top;
  this.knob_a = t;
  this.knob_b = top;
  if (t < top) this.knob_c = 1;
  else this.knob_c = -1;
  clearTimeout(this.to2);
  this.movingSpeed = 1;
  this.accelerateKnob = true;
  this.knobOldY = this.knob_a;
  this.len = Math.abs(this.knob_a - this.knob_b);
  this.animeKnob_();
};

/** Calculate y position of knob from zoom level.
 *  @param {Number} zoom level
 *  @return {Number} calculated y position
 */
GSliderControl.prototype.getKnobTop_ = function(zoom) {
  return this.globals.sliderLength - Math.round(this.globals.sliderLength/this.globals.maxZoom*zoom);
};

/**  Anime moving of knob. Its parameters:  
 *    this.knob_a - knob's actual y position  
 *    this.knob_b - destination y position  
 *    this.knob_c - knob y destination
 */
GSliderControl.prototype.animeKnob_ = function() {
  if (this.len == 0) return;
  if (this.len > 0) {
    var y = Math.abs(5*Math.cos(Math.PI * 1.1 / 2 / this.len * Math.abs(this.knob_a - this.knobOldY))) + 1;
    this.movingSpeed = y;
  } else if (this.accelerateKnob) this.movingSpeed++;
  this.knob_a+=(this.knob_c * this.movingSpeed);
  this.knob.style.top = this.knob_a + 'px';
  if ((this.knob_b >= this.knob_a && this.knob_c == 1) || (this.knob_b <= this.knob_a && this.knob_c == -1)) {
    var me = this;
    this.to2 = me.objectSetTimeout_(this, this.animeKnob_, 0);
  } else this.knob.style.top = this.knob_b + 'px';
};

/**
 * Function called when "zoomend" event is captured on map.
 */
GSliderControl.prototype.setAnimeKnob_ = function(zoomSign) {
  var top = this.getKnobTop_(map.getZoom() + zoomSign);
  this.slide.top = top;
  this.knob_a = parseInt(this.knob.style.top);
  this.knob_b = top;
  this.knob_c = zoomSign*-1;  // invert zoomSign
  clearTimeout(this.to2);
  this.accelerateKnob = false;
  this.animeKnob_();
};

/**
 * Call a function or evaluate an expression after a specified number of
 * milliseconds.
 *
 * Equivalent to the standard window.setTimeout function, but the given
 * function executes as a method of this instance. So the function passed to
 * objectSetTimeout can contain references to this.
 *    objectSetTimeout(this, function() { alert(this.x) }, 1000);
 *
 * @param {Object} object  The target object.
 * @param {Function} command  The command to run.
 * @param {Number} milliseconds  The delay.
 * @return {Boolean} Success.
 */
GSliderControl.prototype.objectSetTimeout_ = function(object, command, milliseconds) {
  return window.setTimeout(function() {
    command.call(object);
  }, milliseconds);
};

/**
 * Function called when "dragend" event is captured on GSliderControl.
 */
GSliderControl.prototype.setZoom_ = function(mode) {
  var G = this.globals;
  map.clearOverlays();
  map.setZoom(Math.round(G.maxZoom - this.slide.top*G.maxZoom/G.sliderLength));
  var knobTop = this.getKnobTop_(map.getZoom());
  this.knob.style.top = knobTop + 'px';
  this.slide.top = knobTop;
};

/**
 * Function called when "mousemove" event is captured on knob.
 * Draw ZoomBox control on map.
 */
GSliderControl.prototype.setZoomBox_ = function() {
  if (!this.zoomBoxParams.enabled) return;

  var
    G = this.globals,
    Z = this.zoomBoxParams,
    mapZoom = map.getZoom(),
    top = parseInt(this.knob.style.top),
    z = Math.round(G.maxZoom - top * G.maxZoom / G.sliderLength);

  if (top <= this.getKnobTop_(mapZoom) && z >= mapZoom) {
    var 
      m = Math.pow(2,(z - mapZoom + 1)),
      x = Math.round(map.getSize().width / m) + 1,
      y = Math.round(map.getSize().height / m) + 1,
      polyPoints = Array(),
      P = G_NORMAL_MAP.getProjection(),
      mapCenter = P.fromLatLngToPixel(map.getCenter(), mapZoom),
      X = mapCenter.x,
      Y = mapCenter.y;
      
    map.clearOverlays();
    
    var knobOffset = Math.round(preloaded[1].height / 2);
    
    // GPolygon is not working correctly at zoom level 0 and 1 so the following
    // code is more complicated than should be... :(
    for (var i = 0;i<10;i++) {
      var x1 = X + i * Math.round( x / 10);
      if (x1 < X+x) polyPoints.push(P.fromPixelToLatLng(new GPoint(x1,Y-y),mapZoom));
    }
    for (var i = 0;i<=20;i++) {
      polyPoints.push(P.fromPixelToLatLng(new GPoint(X+x,(Y-y) + Math.round(i * 2 * y / 20)),mapZoom));
    }
    for (var i = 0;i<=20;i++) {
      polyPoints.push(P.fromPixelToLatLng(new GPoint((X+x) - Math.round(i * 2 * x / 20),Y+y),mapZoom));
    }
     for (var i = 0;i<=20;i++) {
      polyPoints.push(P.fromPixelToLatLng(new GPoint(X-x,(Y+y) - Math.round(i * 2 * y / 20)),mapZoom));
    }
    for (var i = 0;i<=10;i++) {
      polyPoints.push(P.fromPixelToLatLng(new GPoint((X-x) + i * Math.round( x / 10),Y-y),mapZoom));
    }
    
    polyPoints.push(P.fromPixelToLatLng(new GPoint(X,Y-y),mapZoom));
    
    map.addOverlay(new GPolygon(polyPoints,Z.borderColor,Z.borderWidth,1,Z.fillColor,Z.opacity));
	
    if (y > 7 && x > 7) {
      if ((m > 4) || (mapZoom > 0  && m > 2)) {
        polyPoints.length = 0;
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-knobOffset,Y-y),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X+knobOffset,Y-y),mapZoom));    
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X,Y-y-knobOffset),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-knobOffset,Y-y),mapZoom));
        map.addOverlay(new GPolygon(polyPoints,Z.borderColor,Z.borderWidth,1,Z.borderColor,1));
 
        polyPoints.length = 0;
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-knobOffset,Y+y),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X+knobOffset,Y+y),mapZoom));    
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X,Y+y+knobOffset),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-knobOffset,Y+y),mapZoom));
        map.addOverlay(new GPolygon(polyPoints,Z.borderColor,Z.borderWidth,1,Z.borderColor,1));
    
        polyPoints.length = 0;
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-x,Y-knobOffset),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-x,Y+knobOffset),mapZoom));    
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-x-knobOffset,Y),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X-x,Y-knobOffset),mapZoom));
        map.addOverlay(new GPolygon(polyPoints,Z.borderColor,Z.borderWidth,1,Z.borderColor,1));
    
        polyPoints.length = 0;
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X+x,Y-knobOffset),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X+x,Y+knobOffset),mapZoom));    
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X+x+knobOffset,Y),mapZoom));
        polyPoints.push(P.fromPixelToLatLng(new GPoint(X+x,Y-knobOffset),mapZoom));
        map.addOverlay(new GPolygon(polyPoints,Z.borderColor,Z.borderWidth,1,Z.borderColor,1));
      }
    }
  }else map.clearOverlays();
};

/**
 * Is called by GMap2's addOverlay method. 
 * @param {GMap2} map The map that has had this GSliderControl added to it.
 * @return {DOM Object} Div that holds the GSliderControl
 */ 
GSliderControl.prototype.initialize = function(map) {
  //----------------------------------------
  // Declaration of private controls [START]
  //----------------------------------------

  /* utility functions in DragZoomUtil.namespace */
  var GSliderUtils = {};

  /** Enable or disable visibility of pointers.
   *  @param {String} a, its value can be 'hidden' or 'visible'
   */
  GSliderUtils.setPointersVisibility_ = function(a) {
    var bt = getBrowserType_();
    if (bt == 0 || bt == 2 || bt == 5) {
      if (a == 1) b = 'visible'; else b = 'hidden';
      GSliderUtils.streetPointer.container.style.visibility = b;
      GSliderUtils.cityPointer.container.style.visibility = b;
      GSliderUtils.statePointer.container.style.visibility = b;
      GSliderUtils.countryPointer.container.style.visibility = b;
    } else if (bt == 1 || bt == 3|| bt == 4) {
      if (a == 1) b = 'block'; else b = 'none';
      GSliderUtils.streetPointer.container.style.display = b;
      GSliderUtils.cityPointer.container.style.display = b;
      GSliderUtils.statePointer.container.style.display = b;
      GSliderUtils.countryPointer.container.style.display = b;    
    }
  };
  
  /** 
   * Hide pointers 
   */
  GSliderUtils.hidePointers_ = function() {
    GSliderUtils.setPointersVisibility_(0);
  };
  
  /** 
   * Show pointers 
   */
  GSliderUtils.showPointers_ = function() {
    GSliderUtils.setPointersVisibility_(1);
  };
  
  /**
   * Add mouseover and mouseout events to controls. GSliderPointers will display on mouseover and will hide on mouseout.
   * @param {Object} container of control.
   */
  GSliderUtils.addPointerEvent_ = function(container) {
  
    if (GSliderUtils.enableSliderPointers == false) return;
    var that = this;
    GEvent.addDomListener(container, 'mouseover', function() {clearTimeout(that.ti);that.ti = setTimeout(that.showPointers_,100);});
    GEvent.addDomListener(container, 'mouseout', function() {that.ti = setTimeout(that.hidePointers_,500);});
  };
  
  /**
   * Create GSliderPointers and add them to map overlay.
   * @param {Number} opacity of pointers
   */
  GSliderUtils.initPointers_ = function(opacity) { 
    GSliderUtils.streetPointer = new GSliderPointer('Street',17, opacity);
    GSliderUtils.cityPointer = new GSliderPointer('City',14, opacity);
    GSliderUtils.statePointer = new GSliderPointer('State',7, opacity);
    GSliderUtils.countryPointer = new GSliderPointer('Country',4, opacity);
   
    var 
      x = this.pointerX,
      maxY = GSliderUtils.pointerMaxY + 1;
      
    map.addControl(GSliderUtils.streetPointer, new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x, maxY - GSliderUtils.streetPointer.z * GSliderUtils.knobStepY)));
    map.addControl(GSliderUtils.cityPointer, new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x, maxY - GSliderUtils.cityPointer.z * GSliderUtils.knobStepY)));
    map.addControl(GSliderUtils.statePointer, new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x, maxY - GSliderUtils.statePointer.z * GSliderUtils.knobStepY)));
    map.addControl(GSliderUtils.countryPointer, new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x, maxY - GSliderUtils.countryPointer.z * GSliderUtils.knobStepY)));
  };
  
  /**
   * Required by GMaps API for controls. 
   * @return {GControlPosition} Default location for control
   */
  GSliderPointer.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(1, 1));
  };
  
  /** Constructor for GSliderPointer
   *  @param {String} text to display in pointer
   *  @param {Number} zoom level of pointet
   *  @param {Number} opacity of pointers
   */
  function GSliderPointer(text,z,opacity) { 
    
	this.text = text;
    this.z = z; 
    this.container = document.createElement('div');
  
    this.img = new Image();
    this.img.src = 'pointer.png';
    this.container.style.textAlign = 'right';
    this.container.style.cursor = 'pointer';
    if (getBrowserType_() == 5) {
      this.container.style.filter = getLoaderStyle_('pointer.png'); 
    } else {
      this.container.style['-moz-opacity'] = opacity;
      this.container.style['opacity'] = opacity;
      this.container.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';
      this.container.style.backgroundImage = 'url(' + this.img.src + ')';
      this.container.style.backgroundRepeat = "no-repeat";
    }
    
    var bt = getBrowserType_();
    if (bt == 1 || bt == 3 || bt == 4) {
      this.container.style.display = 'none';
    } else if (bt == 0 || bt == 2 || bt == 5) {
      this.container.style.visibility = 'hidden';
    }
    this.container.style.paddingRight = '4px';
    if (getBrowserType_() == 4) {
      this.container.style.paddingTop = '2px';
    } else {
      this.container.style.paddingTop = '1px';
    }
    this.container.style.fontFamily = 'Arial';
    this.container.style.fontWeight = 'bold';
    this.container.style.fontSize = '8pt';
    this.container.innerText = this.text;
    this.container.textContent = this.text; // Firefox
    this.container.style.textAlign = 'right';
    this.container.style.width = (preloaded[4].width - parseInt(this.container.style.paddingRight)) + 'px';
    this.container.style.height = preloaded[4].height + 'px';

    GSliderUtils.addPointerEvent_(this.container);
  };

  /**
   * Declare GSliderPointer control
   */
  GSliderPointer.prototype = new GControl();

  /**
   * Is called by GMap2's addOverlay method. 
   * @param {GMap2} map The map that has had this GSliderPointer added to it.
   * @return {DOM Object} Div that holds the GSliderPointer
   */
  GSliderPointer.prototype.initialize = function() {
    map.getContainer().appendChild(this.container);
    var that = this;
    GEvent.addDomListener(this.container, 'click', function() { map.setZoom(that.z); });
    return this.container;
	
  };
  
  /** Constructor for GZoomInControl
   *  @param {opts_other} Named optional arguments:
   *    @opts_other.x {Number} x position of GSliderControl.
   *    @opts_other.y {Number} y position of GSliderControl.
   *    @opts_other.constolStyle {String} style of GSliderControl.
   */
  function GZoomInControl(controlParams) {
    this.controlParams = controlParams;
  };

  /**
   * Declare GZoomInControl
   */
  GZoomInControl.prototype = new GControl();

  /**
   * Is called by GMap2's addOverlay method. 
   * @param {GMap2} map The map that has had this GZoomInControl added to it.
   * @return {DOM Object} Div that holds the GZoomInControl
   */ 
  GZoomInControl.prototype.initialize = function(map) {
    var container;
    if (getBrowserType_() == 5) {
      container = document.createElement("div"); 
      container.style.height = preloaded[3].height + 'px';
      container.style.width = preloaded[3].width + 'px';
      container.style.filter = getLoaderStyle_('plus.png');
      container.style.backgroundImage = "none";
    } else {
      container = document.createElement('img'); 
      container.src = 'plus.png';
      var opacity = this.controlParams.opacity;
      container.style['-moz-opacity'] = opacity;
      container.style['opacity'] = opacity;
      container.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';
    }
    
    GEvent.addDomListener(container, 'click', function() { map.zoomIn(); });
    map.getContainer().appendChild(container);
    GSliderUtils.addPointerEvent_(container);
    return container;
	
  };
  
  /**
   * Required by GMaps API for controls. 
   * @return {GControlPosition} Default location for control
   */
  GZoomInControl.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(this.controlParams.x, this.controlParams.y)); 
	
  };
  
  /** Constructor for GZoomOutControl
   *    @param {opts_other} Named optional arguments:
   *      @opts_other.x {Number} x position of GSliderControl.
   *      @opts_other.y {Number} y position of GSliderControl.
   *      @opts_other.constolStyle {String} style of GSliderControl.
   */
  function GZoomOutControl(controlParams) {
    this.controlParams = controlParams; 
  };

  /**
   * Declare GZoomOutControl
   */
  GZoomOutControl.prototype = new GControl();

  /**
   * Is called by GMap2's addOverlay method. 
   * @param {GMap2} map The map that has had this GZoomOutControl added to it.
   * @return {DOM Object} Div that holds the GZoomOutControl
   */
  GZoomOutControl.prototype.initialize = function(map) {
    var c = document.createElement('div'); // container
    if (getBrowserType_() == 5) {
    
      c = document.createElement("div"); 
      c.style.height = preloaded[2].height + 'px';
      c.style.width = preloaded[2].width + 'px';
      c.style.filter = getLoaderStyle_('minus.png');
    } else {
      c = document.createElement('img'); 
      c.src = 'minus.png';
      var opacity = this.controlParams.opacity;
      c.style['-moz-opacity'] = opacity;
      c.style['opacity'] = opacity;
      c.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';
    }
    GEvent.addDomListener(c, 'click', function() { map.zoomOut(); });
    map.getContainer().appendChild(c);
    GSliderUtils.addPointerEvent_(c);
    return c;
	
  };        

  /**
   * Required by GMaps API for controls. 
   * @return {GControlPosition} Default location for control
   */
  GZoomOutControl.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(this.controlParams.x, this.controlParams.y + preloaded[3].height + preloaded[0].height)); 
  };
  //--------------------------------------
  // Declaration of private controls [END]
  //--------------------------------------
  this.globals.sliderLength = 0;
  this.draging = false;

  var 
    that = this,
    container = document.createElement('div');
  
  this.knobHeight = preloaded[1].height;
  if (getBrowserType_() == 5) {
    this.knob = document.createElement("div"); 
    this.knob.style.height= this.knobHeight + 'px';
    this.knob.style.width= preloaded[1].width;
    this.knob.style.filter = getLoaderStyle_('knob.png');
  } else {
    this.knob = document.createElement('img'); 
    this.knob.src = 'knob.png';
  }
  container.innerHTML='<img src="slider.png" style="background:url(slider.png)">';
  var opacity = this.controlParams.opacity;
  if (getBrowserType_() != 5) {
    container.style['-moz-opacity'] = opacity;
    container.style['opacity'] = opacity;
    container.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';
  }
  container.appendChild(this.knob);
  this.slide = new GDraggableObject(this.knob, {container:container});
  this.setSlider_(map.getZoom());
  map.getContainer().appendChild(container);
  
  // calculate height of moving area of knob
  this.globals.sliderLength = preloaded[0].height - this.knobHeight;
  GSliderUtils.enableSliderPointers = this.controlParams.enableSliderPointers;
  GSliderUtils.pointerX = this.controlParams.x + preloaded[0].width - 5;
  GSliderUtils.pointerMaxY = this.controlParams.y + preloaded[3].height + this.globals.sliderLength - Math.round(preloaded[1].height / 2);
  GSliderUtils.knobStepY = Math.round(this.globals.sliderLength / (this.globals.maxZoom + 1));
  // init knob position
  this.setZoom_();
  GSliderUtils.initPointers_(this.controlParams.pointerOpacity);
  GEvent.addListener(map, 'zoomend', function(a,b) {that.setSlider_(b);});
  GEvent.addListener(map, 'zoomstart', function(a,b,c) {that.setAnimeKnob_(a);});
  GEvent.addListener(this.slide, 'dragstart', function() {that.draging = true;});
  GEvent.addListener(this.slide, 'dragend', function() {that.setZoom_();});
  GEvent.addListener(this.slide, 'move', function() {that.setZoomBox_();});
  var bt = getBrowserType_();
  if (bt == 0 || bt == 2 || bt == 5) {
    GEvent.addDomListener(container, 'click', function(e) {that.setKnobY_(e.offsetY);});
  } else if (bt == 1 || bt == 3 || bt == 4) {
    GEvent.addDomListener(container, 'click', function(e) {that.setKnobY_(e.layerY);});
  }
  
  GSliderUtils.addPointerEvent_(container);
  // Add ZoomIn and ZoomOut controls to map overlay
  map.addControl(new GZoomInControl(this.controlParams));
  map.addControl(new GZoomOutControl(this.controlParams));
  
  //Customize marker, create it and position it in center of map
	var icon = new GIcon();
	icon.image = '../neutral/images/marker.png';
	icon.iconSize = new GSize(35, 35);
	icon.iconAnchor = new GPoint(16, 16);
	icon.infoWindowAnchor = new GPoint(25, 7);
							
	opts = { 
		"icon": icon,
		"clickable": false,
		"title": "Antolino Brongo",
		"labelOffset": new GSize(-6, -10)
		};
				
	var latlng = new GLatLng(45.528523, -74.042500);	
	var marker = new GMarker(latlng, opts);
	map.addOverlay(marker);
	map.setCenter(new GLatLng(45.530523, -74.050083), 13);
  
  return container;
};
 
/** Set y position of knob
 *  @param {Number} y coordinate of knob
 */
GSliderControl.prototype.setKnobY_ = function(y) {
  if (this.draging == false) {
    var G = this.globals;
    var zoom = Math.round(G.maxZoom - y * G.maxZoom / G.sliderLength);
    this.setSlider_(zoom);
    map.setZoom(zoom);
    this.setSlider_(map.getZoom());
  } else this.draging = false;
};

/**
 * Required by GMaps API for controls. 
 * @return {GControlPosition} Default location for control
 */
GSliderControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(this.controlParams.x, this.controlParams.y + preloaded[3].height)); 
};

/**
 * Return a string which include the style of transparent png images.
 */
function getLoaderStyle_(name) {
  return "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + name + "', sizingMethod='image');";
};

/** Get version number of IE
 *  @return {Number} version of IE
 */
function getInternetExplorerVersion_() {
  var rv = -1;
  if (navigator.appName == 'Microsoft Internet Explorer') {
    if (new RegExp('MSIE ([0-9]{1,}[\.0-9]{0,})').exec(navigator.userAgent) != null) rv = parseFloat( RegExp.$1 );
  }
  return rv;
};

/**
 * Detect brwoser.
 * @return {Number} browser type
 */
function getBrowserType_() {
  var agent = navigator.userAgent.toLowerCase();
  if (agent.indexOf('msie') > -1) {              // IE
    if (getInternetExplorerVersion_() < 7) {
      return 5;                                  // IE6, IE5 or older
    } else {
      return 0;                                  // IE7
    }
  }
  if (agent.indexOf('firefox') > -1) return 1;   // Firefox
  if (agent.indexOf('opera') > -1) return 2;     // Opera
  if (agent.indexOf('navigator') > -1) return 3; // Netscape
  if (agent.indexOf('safari') > -1) return 4;    // Safari
  return -1;
};

/**
 * Image preloading (Please mail me if you know a better or faster solution for image preloading!)
 */
var preloaded = new Array();

GSliderControl.imgPreLoader = function(func) {
    this.callback = func;
    this.loadedImages = 0;
    this.images = new Array('slider.png', 'knob.png', 'minus.png', 'plus.png', 'pointer.png');
    for(var i=0; i<this.images.length; i++){
      preloaded[i] = new Image();
      preloaded[i].onload = this.imgOnLoad;
      preloaded[i].src = this.images[i];
    }
};

GSliderControl.imgOnLoad = function() {
    GSliderControl.loadedImages++;
    if (GSliderControl.loadedImages == GSliderControl.images.length) {GSliderControl.callback()}
}
