//google.load("maps", "3", {other_params:"sensor=false"});
//google.load("search", "1");



// GLOBAL JAVASCRIPT VARIABLES
var map;
var bounds;
var searcher;




/********** http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries **********/
/**
 * @name StyledMarkerMaker
 * @version 0.5
 * @author Gabriel Schneider
 * @copyright (c) 2010 Gabriel Schneider
 * @fileoverview This gives you static functions for creating dynamically
 *     styled markers using Charts API outputs as well as an ability to
 *     extend with custom types.
 */

/**
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var StyledIconTypes = {};
var StyledMarker, StyledIcon;

(function() {
  var bu_ = 'http://chart.apis.google.com/chart?chst=';
  var gm_ = google.maps;
  var gp_ = gm_.Point;
  var ge_ = gm_.event;
  var gmi_ = gm_.MarkerImage;
  

  /**
  * This class is an extended version of google.maps.Marker. It allows
  * styles to be applied that change it's appearance.
  * @extends google.maps.Marker
  * @param {StyledMarkerOptions} StyledMarkerOptions The options for the Marker
  */
  StyledMarker = function(styledMarkerOptions) {
    var me=this;
    var ci = me.styleIcon = styledMarkerOptions.styleIcon;
    me.bindTo('icon',ci);
    me.bindTo('shadow',ci);
    me.bindTo('shape',ci);
    me.setOptions(styledMarkerOptions);
  };
  StyledMarker.prototype = new gm_.Marker();
  
  /**
  * This class stores style information that can be applied to StyledMarkers.
  * @extends google.maps.MVCObject
  * @param {StyledIconType} styledIconType The type of style this icon is.
  * @param {StyledIconOptions} styledIconOptions The options for this StyledIcon.
  * @param {StyledIcon} styleClass A class to apply extended style information.
  */
  StyledIcon = function(styledIconType,styledIconOptions,styleClass) {
    var k;
    var me=this;
    var i_ = 'icon';
    var sw_ = 'shadow';
    var s_ = 'shape';
    var a_ = [];

    function gs_() {
      var image_ = document.createElement('img');
      var simage_ = document.createElement('img');
      ge_.addDomListenerOnce(simage_, 'load', function() {
        var w = simage_.width, h = simage_.height;
        me.set(sw_,new gmi_(styledIconType.getShadowURL(me),null,null,styledIconType.getShadowAnchor(me,w,h)));
        simage = null;
      });
      ge_.addDomListenerOnce(image_, 'load', function() {
        var w = image_.width, h = image_.height;
        me.set(i_,new gmi_(styledIconType.getURL(me),null,null,styledIconType.getAnchor(me,w,h)));
        me.set(s_,styledIconType.getShape(me,w,h));
        image_ = null;
      });
      image_.src = styledIconType.getURL(me);
      simage_.src = styledIconType.getShadowURL(me);
    }

    /**
    * set:
    * This function sets a given style property to the given value.
    * @param {String} name The name of the property to set.
    * @param {Object} value The value to set the property to.
    * get:
    * This function gets a given style property.
    * @param {String} name The name of the property to get.
    * @return {Object}
    */
    me.as_ = function(v) {
      a_.push(v);
      for(k in styledIconOptions) {
        v.set(k, styledIconOptions[k]);
      }
    }

    if (styledIconType !== StyledIconTypes.CLASS) {
      for (k in styledIconType.defaults) {
        me.set(k, styledIconType.defaults[k]);
      }
      me.setValues(styledIconOptions);
      me.set(i_,styledIconType.getURL(me));
      me.set(sw_,styledIconType.getShadowURL(me));
      if (styleClass) styleClass.as_(me);
      gs_();
      me.changed = function(k) {
        if (k!==i_&&k!==s_&&k!==sw_) {
          gs_();
        }
      };
    } else {
      me.setValues(styledIconOptions);
      me.changed = function(v) {
        styledIconOptions[v] = me.get(v);
        for (k = 0; k < a_.length; k++) {
          a_[k].set(v,me.get(v));
        }
      };
      if (styleClass) styleClass.as_(me);
    }
  };
  StyledIcon.prototype = new gm_.MVCObject();
  
  /**
  * StyledIconType
  * This class holds functions for building the information needed to style markers.
  * getURL:
  * This function builds and returns a URL to use for the Marker icon property.
  * @param {StyledIcon} icon The StyledIcon that holds style information
  * @return {String}
  * getShadowURL:
  * This function builds and returns a URL to use for the Marker shadow property.
  * @param {StyledIcon} icon The StyledIcon that holds style information
  * @return {String{
  * getAnchor:
  * This function builds and returns a Point to indicate where the marker is placed.
  * @param {StyledIcon} icon The StyledIcon that holds style information
  * @param {Number} width The width of the icon image.
  * @param {Number} height The height of the icon image.
  * @return {google.maps.Point}
  * getShadowAnchor:
  * This function builds and returns a Point to indicate where the shadow is placed.
  * @param {StyledIcon} icon The StyledIcon that holds style information
  * @param {Number} width The width of the shadow image.
  * @param {Number} height The height of the shadow image.
  * @return {google.maps.Point}
  * getShape:
  * This function builds and returns a MarkerShape to indicate where the Marker is clickable.
  * @param {StyledIcon} icon The StyledIcon that holds style information
  * @param {Number} width The width of the icon image.
  * @param {Number} height The height of the icon image.
  * @return {google.maps.MarkerShape}
  */
  
  StyledIconTypes.CLASS = {};
  
  StyledIconTypes.MARKER = {
    defaults: {
      text:'',
      color:'00ff00',
      fore:'000000',
      starcolor:null
    },
    getURL: function(props){
      var _url;
      var starcolor_=props.get('starcolor');
      var text_=props.get('text');
      var color_=props.get('color').replace(/#/,'');
      var fore_=props.get('fore').replace(/#/,'');
      if (starcolor_) {
        _url = bu_ + 'd_map_xpin_letter&chld=pin_star|';
      } else {
        _url = bu_ + 'd_map_pin_letter&chld=';
      }
      if (text_) {
        text_ = text_.substr(0,2);
      }
      _url+=text_+'|';
      _url+=color_+'|';
      _url+=fore_;
      if (starcolor_) {
        _url+='|'+starcolor_.replace(/#/,'');
      }
      return _url;
    },
    getShadowURL: function(props){
      if (props.get('starcolor')) {
        return bu_ + 'd_map_xpin_shadow&chld=pin_star';
      } else {
        return bu_ + 'd_map_pin_shadow';
      }
    },
    getAnchor: function(props,width,height){
      return new gp_(width / 2,height);
    },
    getShadowAnchor: function(props,width,height){
      return new gp_(width / 4,height);
    },
    getShape: function(props,width,height){
      var _iconmap = {};
      _iconmap.coord = [
        width / 2, height,
        (7 / 16) * width, (5 / 8) * height,
        (5 / 16) * width, (7 / 16) * height,
        (7 / 32) * width, (5 / 16) * height,
        (5 / 16) * width, (1 / 8) * height,
        (1 / 2) * width, 0,
        (11 / 16) * width, (1 / 8) * height,
        (25 / 32) * width, (5 / 16) * height,
        (11 / 16) * width, (7 / 16) * height,
        (9 / 16) * width, (5 / 8) * height
      ];
      for (var i = 0; i < _iconmap.coord.length; i++) {
        _iconmap.coord[i] = Math.round(_iconmap.coord[i]);
      }
      _iconmap.type = 'poly';
      return _iconmap;
    }
  };
  StyledIconTypes.BUBBLE = {
    defaults: {
      text:'',
      color:'00ff00',
      fore:'000000'
    },
    getURL: function(props){
      var _url = bu_ + 'd_bubble_text_small&chld=bb|';
      _url+=props.get('text')+'|';
      _url+=props.get('color').replace(/#/,'')+'|';
      _url+=props.get('fore').replace(/#/,'');
      return _url;
    },
    getShadowURL: function(props){
      return bu_ + 'd_bubble_text_small_shadow&chld=bb|' + props.get('text');
    },
    getAnchor: function(props,width,height){
      return new google.maps.Point(0,42);
    },
    getShadowAnchor: function(props,width,height){
      return new google.maps.Point(0,44);
    },
    getShape: function(props,width,height){
      var _iconmap = {};
      _iconmap.coord = [
        0,44,
        13,26,
        13,6,
        17,1,
        width - 4,1,
        width,6,
        width,21,
        width - 4,26,
        21,26
      ];
      _iconmap.type = 'poly';
      return _iconmap;
    }
  };
})();





document.observe('dom:loaded', function() {
    $$('.featurecontainer').each(function(el){
		var myClasses = $w(el.className);
		for (var i=0; i < myClasses.length; i++) {
			var matches = /feat(\d+)(a\d+)?/i.exec(myClasses[i]);
			if (matches != null && matches.length > 1) {
		    	el.observe('mouseover', function(evt) {
		    		el.writeAttribute('rotate', 'false');
		    	});
		    	el.observe('mouseout', function(evt) {
		    		el.writeAttribute('rotate', 'true');
		    	});
		    	var params = $H({num: matches[1]});
		    	if (matches.length > 2 && !Object.isUndefined(matches[2])) {
		    		params.set('agent', matches[2].substr(1));
		    	}

		    	var featRotate = function(){
		    		if (!el.hasAttribute('rotate') || (el.readAttribute('rotate') == 'true')) {
		    			var elId = el.identify();
		    			var elHeight = el.getHeight();
		    			el.descendants().each(function (ele){
		    				if (elHeight < ele.getHeight()) {
		    					elHeight = ele.getHeight();
		    				}
		    			});
		    			el.setStyle({height: elHeight+'px'});
			    		new Ajax.Updater(elId, './features.php', {
			    			method: 'get',
			    			parameters: params
			    		});
		    		}
		    	}
		    	featRotate();
		    	setInterval(featRotate, 10000);
			}
		}
    });

    $$('img.gallery').invoke('observe', 'mouseover', function(evt) {
        evt.stop();
        if (this.up('.gcontainer') != null) {
            var imgDisplay = this.up('.gcontainer').down('img.gdisplay');
            if (imgDisplay != null) {
                var parCurrent = $H(imgDisplay.src.toQueryParams());
                var parNew = $H(this.src.toQueryParams());
                if (parCurrent.get('s')) {
                    parNew.set('s', parCurrent.get('s'));
                } else {
                    parNew.unset('s');
                }
                var srcNew = this.src.replace(/([^?]+).*/, "$1") + "?" + parNew.toQueryString();
                if ((srcNew != imgDisplay.src) && ((imgDisplay.readAttribute('paused') == null) || (imgDisplay.readAttribute('paused') == "false"))) {
                    imgDisplay.writeAttribute('paused', "true");
                    $('loader').src = srcNew;
                    $('gwrapper').setStyle({
                        height: $(imgDisplay).getHeight()+'px',
                        width: $(imgDisplay).getWidth()+'px'
                    });
                    new Effect.Fade(imgDisplay, {
                        duration:0.2,
                        afterFinish:function(effect){
                            imgDisplay.src = srcNew;
                            imgDisplay.writeAttribute('paused', "false");

                            new Effect.Appear(imgDisplay, {
                                duration: 0.2,
                                afterFinish:function(effect){
                                    imgDisplay.writeAttribute('paused', "false");
                                }
                            });
                        }
                    }); 
                }
            }
        }
    });


    if ($('MortgageCalc') != null) {
        MortgageCalc($('MortgageCalc'));
    }


    if ((typeof markers != 'undefined') && Object.isArray(markers) && (markers.length > 0) && $("map_canvas") != null) {
        $$('#map_container').invoke('show');
        
        var latlng = new google.maps.LatLng(33.2094, -87.5695);
        var myOptions = {
            zoom: 8,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        map = new google.maps.Map($("map_canvas"), myOptions);
        for (var i=0; i < markers.length; i++) {
            addMapMarker(markers[i]);
        }
        if (markers.length == 1) {
            map.setCenter(new google.maps.LatLng(markers[0]['lat'], markers[0]['lon']));
            map.setZoom(14);
        } else {
            map.fitBounds(bounds);
        }
    }
});


function addMapMarker(listing) {
    var loc = new google.maps.LatLng(listing['lat'], listing['lon']);
    var marker = new StyledMarker({
        map: map,
        position: loc,
        title: listing['idx']+'. $'+listing['price'],
        styleIcon: new StyledIcon(StyledIconTypes.BUBBLE,{
            color: (listing['recent'] == 1) ? 'ff0000' : '00cc00',
            text: listing['idx']
        })
    });
    bounds.extend(loc);

    var tContent = infoContent;
    ['price', 'mls', 'address', 'beds', 'baths', 'sqft', 'link'].each(function(i){
    	if (!Object.isUndefined(listing[i])) {
    		tContent = tContent.gsub('%'+i+'%', listing[i]);
    	}
    });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(tContent);
        infowindow.open(map, marker);
    });
}


var localMapResults = $H({});
function mDisplay(el) {
    var elContainer = $(el).up('.gmapopts');
    if (elContainer != null) {
        var mapZoom = 1; //map.getZoom();
        if (localMapResults.get(mapZoom) == null) {
            localMapResults.set(mapZoom, $H({}));
        }

        elContainer.select('input.gopt').each(function(i){
            var searchText = i.up().select('span.gval').first();
            
            if (searchText != null) {
                searchText = searchText.innerHTML;

                if (i.checked) {
                    // Local search option is checked
                    if (Object.isHash(localMapResults.get(mapZoom).get(searchText))) {
                        // Markers were previously found and should be shown
                        localMapResults.get(mapZoom).get(searchText).get('markers').each(function(m){
                            m.setVisible(true);
                        });

                    } else {
                        // Find and display markers
                        localMapResults.get(mapZoom).set(searchText, $H({
                            results: [],
                            markers: []
                        }));
                        // Initialize a LocalSearch instance
                        searcher = new google.search.LocalSearch();
    //                    searcher.setCenterPoint(map); // bind the searcher to the map
                        searcher.setCenterPoint(new google.maps.LatLng(markers[0]['lat'], markers[0]['lon'])); // bind the searcher to the map
                        searcher.setAddressLookupMode(google.search.LocalSearch.ADDRESS_LOOKUP_DISABLED); // Search results only (no addresses)
                        searcher.setResultSetSize(google.search.Search.LARGE_RESULTSET);
                        searcher.setSearchCompleteCallback(searcher, function(){
                            this.results.each(function(r){
                                localMapResults.get(mapZoom).get(searchText).get('results').push(r);
                                var markerLatLng = new google.maps.LatLng(parseFloat(r.lat), parseFloat(r.lng));

                                var gColor  = i.up().select('span.gcolor').first().innerHTML;
                                var gLetter = i.up().select('span.gletter').first().innerHTML;
                                
                                // Create the marker
                                var marker = new StyledMarker({
                                    position: markerLatLng,
                                    map: map,
                                    visible: true,
                                    flat: true,
                                    result: r,
                                    myHTML: new Element('div').update(r.html.cloneNode(true)),
                                    styleIcon: new StyledIcon(StyledIconTypes.MARKER,{
                                        color: gColor,
                                        text:  gLetter
                                    })
                                });
                                google.maps.event.addListener(marker, "click", function(){
                                    infowindow.setContent(marker.myHTML);
                                    infowindow.open(map, marker);
                                });
                                localMapResults.get(mapZoom).get(searchText).get('markers').push(marker);
                            });

                            if (this.cursor && this.cursor.currentPageIndex+1 < this.cursor.pages.length) {
                                // Go to the next page.
                                this.gotoPage(this.cursor.currentPageIndex+1);
                            }
                        }); 
                        searcher.execute(searchText);
                    }

                } else if (Object.isHash(localMapResults.get(mapZoom).get(searchText)) && Object.isArray(localMapResults.get(mapZoom).get(searchText).get('markers'))) {
                    // Markers were previously displayed but now should be hidden (Local search option is unchecked)
                    localMapResults.get(mapZoom).get(searchText).get('markers').each(function(m){
                        m.setVisible(false);
                    });
                }
            }
        });
    }
}





function MortgageCalc(form) {
    // Adds the first comma for 1 or 2 digits
    var re1 = /^(\d{1,2})(?=(\d\d\d)+(\.|$))/;
    // Adds commas for every group of 3 digits
    var re2 = /(\d\d\d)(?=(\d\d\d)+(\.|$))/g;

    var LoanAmount         = parseFloat(form.LoanAmount.value.gsub(/[^0-9.]/, ''));
    var DownPayment        = parseFloat(form.DownPayment.value.gsub(/[^0-9.]/, ''));
    var AnnualInterestRate = parseFloat(form.InterestRate.value.gsub(/[^0-9.]/, ''));
    var Years              = parseFloat(form.NumberOfYears.value.gsub(/[^0-9.]/, ''));

    form.LoanAmount.value  = String(LoanAmount).replace(re1, "$1,").replace(re2, "$1,");
    form.DownPayment.value = String(DownPayment).replace(re1, "$1,").replace(re2, "$1,");

    if (isNaN(LoanAmount) || isNaN(DownPayment) || isNaN(AnnualInterestRate) || isNaN(Years)) {
        return false;
    }
    var MonthRate          = AnnualInterestRate/100/12;
    var NumPayments        = Years*12;
    var Prin               = LoanAmount-DownPayment;
    var MonthPayment       = String(Math.max(0, Math.floor((Prin*MonthRate)/(1-Math.pow((1+MonthRate),(-1*NumPayments)))*100)/100)).replace(re1, "$1,").replace(re2, "$1,").replace(/(\.\d)$/, "$10");

    $('MonthlyPayment').update("$"+MonthPayment);
    return false;
}









Ajax.AutocompleterIE = Class.create(Ajax.Autocompleter, {
    initialize: function($super, element, update, url, options) {
        $super(element, update, url, options);
        this.element.observe('focus', this.checkShowMessage.bind(this));
    },
    checkShowMessage: function(evt){
        this.element.writeAttribute('isFocused', '1');
//      console.log("checkShowMessage");

        // Move the cursor to the end of the user inputted text
        if (evt.element().setSelectionRange) {
            evt.element().setSelectionRange(evt.element().value.length, evt.element().value.length);
        } else if (evt.element().createTextRange) {
            var FieldRange = evt.element().createTextRange();
            FieldRange.moveStart('character', evt.element().value.length);
            FieldRange.collapse();
            FieldRange.select();
        }

        // Ignore this focus event the first time onBlur fires
        // (IE fires when you scroll the list of choices)
        if (!Object.isUndefined(this.noUpdate) && this.noUpdate) {
            this.noUpdate = false;
        } else {
            if (Object.isUndefined(this.ignoreScrollBar) || !this.ignoreScrollBar) {
                // Do something on entering autocomplete field if not scrolling the choices list
            }
        }
    },

    onComplete: function(request) {
//        this.updateChoices(request.responseText);
        var myUl = new Element('div').update(request.responseText).down();
        myUl.observe('scroll', this.ignoreIeScroll.bind(this));
        this.updateChoices(myUl);
    },
    onBlur: function($super, event) {
        this.noUpdate = true;
        if (!Object.isUndefined(this.ignoreScrollBar) && this.ignoreScrollBar) {
//          console.log("ingore blur input");
            //var el = event.element();
            event.stop();
            event.element().focus();
        } else {
//          console.log("blur input start");
            if (this.element.readAttribute('isFocused') == "1") {
                if (!Object.isUndefined(this.ignoreBlurTimer) && this.ignoreBlurTimer != null) {
                    clearTimeout(this.ignoreBlurTimer);
//                  console.log("Clear blur timeout" + this.ignoreBlurTimer);
                    this.ignoreBlurTimer = null;
                }
                this.element.writeAttribute('isFocused', '0');
                this.ignoreBlurTimer = setTimeout(function(){
                    this.noUpdate = false;
                    //var test = this;
                    var t = this.element.readAttribute('isFocused');
                    if (t != "1") {
//                      console.log("blur input");
                        if (Object.isUndefined(this.ignoreScrollBar) || !this.ignoreScrollBar) {
                            if (this.index > 0) {
                                this.selectEntry();
                            }
                            $super();
/*** only for facebook style address list
                            //move itself back to the end on blur
                            if (this.wrapper.nextSiblings().length > 0) {
                                this.wrapper.nextSiblings().last().insert({
                                    after: this.wrapper
                                });
                            }
*/
                        }
                    }
                }.bind(this), 250);
            }
        }
    },

    ignoreIeScroll: function() {
        if (!Object.isUndefined(this.ignoreScrollTimer) && this.ignoreScrollTimer != null) {
            clearTimeout(this.ignoreScrollTimer);
//          console.log("Clear scroller timeout" + this.ignoreScrollTimer);
            this.ignoreScrollTimer = null;
        }
        this.ignoreScrollBar = true;
        this.ignoreScrollTimer = setTimeout(function(){
//          console.log("Honor Scroll Close");
            this.ignoreScrollBar = false;
            this.noUpdate = true;
            this.element.focus();
        }.bind(this), 900);
//      console.log("Start scroller timeout" + this.ignoreScrollTimer);
    }

});









/**
 *    Basic Slideshow App
 *    
 *    Plagerised from Tom Doyle by Isotope Communications Ltd, Dec 2008
 *    http://www.tomdoyletalk.com/2008/10/28/simple-image-gallery-slideshow-with-scriptaculous-and-prototype/
 *    
 *    Published [16/12/08]:
 *    http://www.icommunicate.co.uk/articles/all/simple_slide_show_for_prototype_scriptaculous_38/    
 *
 *    Changes: Basically made it an object so that you can run multiple instances and so that
 *             it doesn't get interfered with by other scripts on the page.
 *    
 *             Have also added a few things, like "Captions" and the option of changing the
 *             effects..
 *
 *    [24/01/10]: J. Johanson, fixed "this.play.bind" bug
 *    [27/01/10]: J. Johanson, added goTo method
 *    [27/01/10]: J. Johanson, added runrandom flag
 *    [02/02/10]: J. Johanson, fixed bug where image goes blank when goNext, goPrevious, goTo called during fade
 *
 *    Example:
 *            Event.observe(window, 'load', function(){
 *                oMySlides = new iSlideShow({
 *                    autostart     : true        // optional, boolean (default:true)
 *                    runrandom     : false        // optional, boolean (default:false)
 *                    start        : 0,         // optional, slides[start] (default:0) 
 *                    wait         : 4000,     // optional, milliseconds (default:4s)
 *                    duration    : 0.5,         // optional, seconds (default:0.5s)
 *                    slides         : [
 *                        'image-div-a', 
 *                        'image-div-b', 
 *                        'image-div-c', 
 *                        'image-div-d' 
 *                    ],
 *                    counter        : 'counter-div-id', // optional...
 *                    caption     : 'caption-div-id', // optional... 
 *                    playButton    : 'PlayButton',     // optional (default:playButton)
 *                    pauseButton    : 'PauseButton',     // optional (default:PauseButton)
 *                });
 *            });
 *
 *            To start the slideshow:
 *                oMySlides.startSlideShow();
 *
 *            To skip forward, back, stop:
 *                oMySlides.goNext();
 *                oMySlides.goPrevious();
 *                oMySlides.stop();
 *                oMySlides.goTo(iImageIdNext);
 */
/*
var iSlideShow = new Class.create();
iSlideShow.prototype = {
    initialize : function (oArgs){
        this.wait             = oArgs.wait ? oArgs.wait : 4000;
        this.start             = oArgs.start ? oArgs.start : 0;
        this.duration        = oArgs.duration ? oArgs.duration : 0.5;
        this.autostart        = (typeof(oArgs.autostart)=='undefined') ? true : oArgs.autostart;
        this.runrandom        = (typeof(oArgs.runrandom)=='undefined') ? false : oArgs.runrandom;
        this.slides         = oArgs.slides;
        this.counter        = oArgs.counter;
        this.caption        = oArgs.caption;
        this.playButton        = oArgs.playButton ? oArgs.playButton : 'PlayButton';
        this.pauseButton    = oArgs.pauseButton ? oArgs.pauseButton : 'PauseButton';
        this.iImageId        = this.start;
        this.eAppear        = null;
        this.eFade            = null;
        if ( this.slides ) {
            this.numOfImages    = this.slides.length;
            if ( !this.numOfImages ) {
                alert('No slides?');
            }
        }
        
        if (this.runrandom) {
            var a,b;        
            a = this.slides.slice( 0, 1);
            b = this.slides.slice( 1).sort(function() {return 0.5 - Math.random()})
            this.slides = a.concat( b);
        }
        
        if ( this.autostart ) {
            this.startSlideShow();
        }
    },
    
    // The Fade Function
    swapImage: function (x,y) {
        $(this.slides[x]) && ( this.eAppear = new Effect.Appear( this.slides[x]), { duration: this.duration });
        this.eFade && this.eAppear && ( this.eFade.element === this.eAppear.element) && this.eFade.cancel();
        $(this.slides[y]) && ( this.eFade   = new Effect.Fade  ( this.slides[y]), { duration: this.duration });
    },
    
    // the onload event handler that starts the fading.
    startSlideShow: function () {
        this.playid = setInterval(this.play.bind(this),this.wait);
        $(this.playButton).hide();
        $(this.pauseButton).appear({ duration: 0});

        this.updatecounter();
                                    
    },
    
    play: function () {
        
        var imageShow, imageHide;
    
        imageShow = this.iImageId+1;
        imageHide = this.iImageId;
        
        if (imageShow == this.numOfImages) {
            this.swapImage(0,imageHide);    
            this.iImageId = 0;                    
        } else {
            this.swapImage(imageShow,imageHide);            
            this.iImageId++;
        }
        
        this.updatecounter();
    },
    
    stop: function  () {
        clearInterval(this.playid);                
        $(this.playButton).appear({ duration: 0});
        $(this.pauseButton).hide();
    },
    
    goNext: function () {
        clearInterval(this.playid);
        $(this.playButton).appear({ duration: 0});
        $(this.pauseButton).hide();
        
        var imageShow, imageHide;
    
        imageShow = this.iImageId+1;
        imageHide = this.iImageId;
        
        if (imageShow == this.numOfImages) {
            this.swapImage(0,imageHide);    
            this.iImageId = 0;                    
        } else {
            this.swapImage(imageShow,imageHide);            
            this.iImageId++;
        }
    
        this.updatecounter();
    },
    
    goPrevious: function () {
        clearInterval(this.playid);
        $(this.playButton).appear({ duration: 0});
        $(this.pauseButton).hide();
    
        var imageShow, imageHide;
                    
        imageShow = this.iImageId-1;
        imageHide = this.iImageId;
        
        if (this.iImageId == 0) {
            this.swapImage(this.numOfImages-1,imageHide);    
            this.iImageId = this.numOfImages-1;        
        } else {
            this.swapImage(imageShow,imageHide);            
            this.iImageId--;
        }
        
        this.updatecounter();
    },
    
    goTo: function (iImageIdNext) {
        var imageShow, imageHide;
                    
        clearInterval(this.playid);
        $(this.playButton).appear({ duration: 0});
        $(this.pauseButton).hide();

        imageShow = iImageIdNext;
        imageHide = this.iImageId;
        
        if( imageShow != imageHide) {
            this.swapImage(imageShow,imageHide);            
            this.iImageId = iImageIdNext;
            this.updatecounter();
        }
    },
    
    updatecounter: function () {
        var textIn = this.iImageId+1 + ' of ' + this.numOfImages;
        $(this.counter) && ( $(this.counter).innerHTML = textIn );
        if ( $(this.caption) && ( oNewCaption = $(this.slides[this.iImageId]).down('.image-caption') ) ) {
            $(this.caption).innerHTML = oNewCaption.innerHTML;
        }
    }
}






//Main SlideShow Class:
//EXAMPLE USAGE:
//new SlideShow('container', { slideDuration: 2 });
var SlideShow = Class.create({
  initialize: function(element, options){
    this.element = element;
    this.suppliedOptions = options;
    this.defaultOptions = $H({
      autoPlay: true,
      slideDuration: 5,
      transitionDuration: 1,
      loop: true,
      crossFade: false,
      pauseOnMouseover: false,
      slidesSelector: '> *',
      startHidden: true,
      events: { init: 'dom:loaded', play: 'window:loaded' },
      beforeStart: Prototype.emptyFunction, afterFinish: Prototype.emptyFunction
    });
    
    // assigning the options to internal variables
    this.options = this.defaultOptions.merge(this.suppliedOptions).each(function(option){
      this[option[0]] = option[1];
    }.bind(this));
    
    this.events = $H(this.defaultOptions.get('events')).merge(this.events).toObject();
    
    if (this.autoPlay) {
      this.initEventFunction = function(){
        this.init();
        // only allow the slideShow to observe one 'dom:loaded' event
        if (this.events.init == 'dom:loaded')
          document.stopObserving(this.events.init, this.initEventFunction);
      }.bind(this);
      document.observe(this.events.init, this.initEventFunction);
    }
  },
  
  init: function(){
    if (!$(this.element)) return;
    this.root = $(this.element);
    this.id = this.root.identify();
    this.fireEvent('initializing', { slideShow: this });
    this.slides = $$('#' + String(this.id) + ' ' + String(this.slidesSelector));
    this.loopCount = 0;
    this.slideCount = 0;
    this.slideIndex = 0;
    this.paused = false;
    this.started = false;
    
    this.prep();
    
    this.playEventFunction = function(){
      this.beforeStart();
      this.play();
      if (this.pauseOnMouseover)
        this.root.observe('mouseover', this.pause.bind(this)).observe('mouseout', this.play.bind(this));
      
      // only let window:loaded start the slideShow once
      if (this.events.play == 'window:loaded')
        document.stopObserving(this.events.play, this.playEventFunction);
    }.bind(this);
    document.observe(this.events.play, this.playEventFunction);
    
    this.fireEvent('initialized', { slideShow: this });
  },
  
  prep: function(){
    this.root.makePositioned();
    
    for (var i=0; i < this.slides.length; i++) {
      this.slides[i].setStyle({ position: 'absolute', zIndex: i });
      if (this.startHidden || (!this.startHidden && i != 0))
        this.prepSlide(this.slides[i]);
    };
    this.fireEvent('prepped', { slideShow: this });
    this.play();
    if (this.pauseOnMouseover)
        this.root.observe('mouseover', this.pause.bind(this)).observe('mouseout', this.play.bind(this));
  },
  
  prepSlide: function(slide){
    return slide.setStyle({ display: 'none', opacity: 0 });
  },
  
  play: function(e){
    // prevent mousing out from causing the slideShow to start
    if (e && !this.autoPlay && this.pauseOnMouseover && this.loopCount == 0) return;
    
    // prevent against internal mouse movements from triggering a transition
    if (e && this.mouseIsWithinSlideArea(e)) return;
    
    this.started = true;
    this.paused = false;
    this.fireEvent('started', { slideShow: this });
    this.transition();
  },
  
  pause: function(e){
    // if it's not started playing, or if it's already paused, or if the mouse isn't within the slide area return
    if (!this.started || this.paused || (e && !this.mouseIsWithinSlideArea(e))) return;
    
    this.paused = true;
    this.abortNextTransition();
    
    // queue paused test
    // this.setupPausedTest();
    
    this.fireEvent('paused', { slideShow: this });
  },
  
  transition: function(){
    if (this.paused) return;
    if (this.nextTransition) this.nextTransition.stop();
    
    this.coming = this.slides[this.slideIndex];
    this.going = this.coming.previous() || this.slides.last();
    
    var coming = this.coming;
    var going = this.going;
    
    if (this.slideCount > 0 && this.coming == this.slides.first() && this.going == this.slides.last()) {
      this.fireEvent('looped', { slideShow: this });
      this.loopCount++;
      this.afterFinish();
      if (!this.loop) return;
    }
    
    this.slideCount++;
    this.slideIndex++;
    if (this.slideIndex >= this.slides.length) this.slideIndex = 0;
    
    // if not fresh start, fade
    if (going != coming) {
      if (this.crossFade) {
        new Effect.Parallel(
          [new Effect.Appear(coming), new Effect.Fade(going)],
          {
            duration: this.transitionDuration,
            afterFinish: function(){
              this.prepSlide(going);
              this.afterTransitionEffect();
            }.bind(this)
          }
        );
      } else {
        going.fade({
          duration: this.transitionDuration / 2,
          afterFinish: function(){
            this.prepSlide(going);
            coming.appear({
              duration: this.transitionDuration / 2,
              afterFinish: this.afterTransitionEffect.bind(this)
            });
          }.bind(this)
        });
      }
    }
    // fade in the first time
    else {
      coming.appear({
        duration: this.transitionDuration / 2,
        afterFinish: this.afterTransitionEffect.bind(this)
      });
    }
    this.fireEvent('transitioned', { slideShow: this, coming: coming, going: going, loopCount: this.loopCount });
  },
  
  afterTransitionEffect: function(){
    this.scheduleNextTransition();
  },
  
  scheduleNextTransition: function(){
    if (this.slideDuration <= 0) return;
    this.nextTransition = new PeriodicalExecuter(function(nextTransition){
      if (this.paused) return;
      this.transition();
    }.bind(this), this.slideDuration);
  },
  
  abortNextTransition: function(){
    if (this.nextTransition) this.nextTransition.stop();
  },
  
  fireEvent: function(name, memo){
    this.root.fire('SlideShow_' + this.root.id + ':' + name, memo);
  },
  
  mouseIsWithinSlideArea: function(e){
    var offsets = this.root.cumulativeOffset();
    var maxX = offsets.left + this.root.getWidth();
    var minX = offsets.left;
    var maxY = offsets.top + this.root.getHeight();
    var minY = offsets.top;
    
    // minX and the maxY need to be checked like this
    if (minX == e.pointerX() || maxY == e.pointerY()) return false;
    if ($R(minX, maxX).include(e.pointerX()) && $R(minY, maxY).include(e.pointerY())) {
      return true; } else { return false; }
  },
  
  end: function(){
    this.pause();
    document.stopObserving(this.events.play, this.playEventFunction);
    document.stopObserving(this.events.init, this.initEventFunction);
  },
  
  remove: function(){
    this.end();
    this.root.remove();
    this.fireEvent('removed');
  }
});
*/



/*
Cette création est mise à disposition selon le Contrat Paternité-Partage des Conditions Initiales à l'Identique 3.0 Unported disponible en ligne http://creativecommons.org/licenses/by-sa/3.0/ ou par courrier postal à Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
*/
/* extension prototype */
Object.extend(Event, {
        wheel:function (event){
        var delta = 0;
        if (event.wheelDelta) {
            delta = event.wheelDelta/120;
            if (window.opera) delta = -delta;
        } else if (event.detail) {
            delta = -event.detail/3;
        }
        if(navigator.userAgent.indexOf('Mac') != -1) delta = -delta;      
        return Math.round(delta);
    }
});
var Horinaja = Class.create();
Horinaja.prototype = {
    initialize: function(capture, duree, secExecution, pagination){
        this.capture = capture;
        this.duree = duree;
        this.secExecution = secExecution;
        this.pagination = pagination;
        this.nCell = 0;
        this.id = 1;
        this.po = 0;    
        this.f = $$('div#'+this.capture+' ul li');
        this.px = $(this.capture).getWidth();
        this.f.invoke('hide');
        this.f.first().show();
        this.pxH = $(this.capture).getHeight();
        this.start();
    },
    start: function(){        
        this.nCell = this.f.length;    

        $(this.capture).setStyle({
            overflow:'hidden',
            position:'relative'
        });
        $(this.capture).firstDescendant().setStyle({
            width:(this.px*this.nCell)+'px'
        });
        this.f.invoke('show');

        this.mover = $(this.capture).firstDescendant();    
        for (i=0;i!=this.nCell;i++){
            this.f[i].setStyle({
                width: this.px+'px',
                height: (this.pxH-40)+'px',
                float: 'left'
            });    
        }
                
        if (this.pagination){
            $(this.capture).insert({bottom:'<ol class="horinaja_pagination"></ol>'});
            this.olPagination  = $(this.capture).firstDescendant().next();
            $(this.olPagination).setStyle({
                width: this.px+'px'
            });
            this.wb = Math.floor(this.px/this.f.length);
/*
            for(i=1;i!=(this.f.length+1);i++){
                $(this.olPagination).insert({bottom:'<li><a style="width:'+this.wb+'px;">'+i+'</a></li>'});
                if(i!=this.id){
                    $(this.olPagination).childElements()[i-1].setStyle({
                        opacity:0.2
                        });                    
                }
            }
*/
            for (i=this.f.length; i>=1;i--){
                $(this.olPagination).insert({bottom:'<li><a>'+i+'</a></li>'});
                if(i!=this.id){
                    $(this.olPagination).childElements()[this.f.length-i].setStyle({
                        opacity:0.2
                        });                    
                }
            }

            $(this.olPagination).childElements()[this.f.length-1].setStyle({
                opacity:1
            });    
            this.startOC();
        }
        this.startPe();
        Event.observe($(this.capture),"mouseout", this.startPe.bind(this));
        Event.observe($(this.capture),"mouseover", this.stopPe.bind(this));                                
        Event.observe($(this.capture), "mousewheel", this.wheelwheel.bind(this));        
        Event.observe($(this.capture), "DOMMouseScroll", this.wheelwheel.bind(this));                
    },
    startOC: function(){
    	Event.observe($(this.olPagination),"click", this.moveP.bind(this));
    },
    startPe: function(){
    	this.periodik = new PeriodicalExecuter(this.Pe.bind(this),this.secExecution);    
    },
    stopPe: function(){
    	this.periodik.stop();
    },
    effaceP: function(mop){
        this.mop = mop;
        if(this.pagination)
        new Effect.Fade($(this.olPagination).childElements()[this.f.length-this.mop],{duration:0.3,to:0.2})
    },
    move: function(xp){
        this.xp = xp;
        new Effect.Move(this.mover, { 
            x: this.xp, 
            y: 0,
            mode:'absolute',
            duration: this.duree,
            transition: Effect.Transitions.sinoidal
        });
        if(this.pagination){
            new Effect.Appear($(this.olPagination).childElements()[this.f.length-this.id],{duration:0.3,to:1})
        }    
    },    
    Pe: function(){
        if(this.id<this.nCell){
            this.po=this.po-this.px;
            this.effaceP(this.id);
            this.id=this.id+1;
            this.move(this.po);
        }else{
            this.po=0;
            this.effaceP(this.id);
            this.id=1;
            this.move(this.po);
        }
    },
    moveP: function(evt){
        var child = Event.element(evt);
        this.occ = parseInt(child.innerHTML);
        if(this.id>this.occ){
            this.diff= this.id-this.occ;
            this.po=this.po+(this.px*this.diff);
            this.effaceP(this.id);
            this.id=this.occ;
            this.move(this.po);
        }else if(this.id<this.occ){
            this.diff= this.occ-this.id;
            this.po=this.po-(this.px*this.diff);
            this.effaceP(this.id);
            this.id=this.occ;
            this.move(this.po);
        }
    },
    stopEvent:function(pE)
    {
       if (!pE)
         if (window.event)
           pE = window.event;
         else
           return;
      if (pE.cancelBubble != null)
         pE.cancelBubble = true;
      if (pE.stopPropagation)
         pE.stopPropagation();
      if (pE.preventDefault)
         pE.preventDefault();
    } ,
    wheelwheel: function(e){
        this.event = e;
        this.stopPe();
        this.stopEvent(e);
        if (Event.wheel(this.event) < 0){
            if(this.id<this.nCell){
                this.po=this.po-this.px;
                this.effaceP(this.id);
                this.id=this.id+1;
                this.move(this.po);
            }
        } else{
            if (this.id!=1){
                this.po=this.po+this.px;
                this.effaceP(this.id);
                this.id=this.id-1;
                this.move(this.po);
            }
        }
    }
};

