/**
 * MooScroll beta [for mootools 1.2]
 * @author Jason J. Jaeger | greengeckodesign.com
 * @version 0.59
 * @license MIT-style License
 *			Permission is hereby granted, free of charge, to any person obtaining a copy
 *			of this software and associated documentation files (the "Software"), to deal
 *			in the Software without restriction, including without limitation the rights
 *			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *			copies of the Software, and to permit persons to whom the Software is
 *			furnished to do so, subject to the following conditions:
 *	
 *			The above copyright notice and this permission notice shall be included in
 *			all copies or substantial portions of the Software.
 *	
 *			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *			THE SOFTWARE.
 **/
var MooScroll = new Class({
	Implements: Options,
	options: {
		selector: ".scroll",
		increment: 30,
		upBtnClass: "upBtn",
		downBtnClass: "downBtn",
		scrollBarClass: "scrollBar",
		scrollHandleClass: "scrollHandle",
		scrollHandleBGClass: "scrollHandleBG",
		scrollHandleTopClass: "scrollHandleTop",
		scrollHandleMiddleClass: "scrollHandleMiddle",
		scrollHandleBottomClass: "scrollHandleBottom",
		scrollControlsYClass: "scrollControlsY",
		handleOpacity: 1,
		handleActiveOpacity: 0.85,
		disabledOpacity: 0.5,
		fullWindowMode: false,
		smoothMooScroll: {
			toAnchor: true,
			toMooScrollArea: true
		},
		restrictedBrowsers: [Browser.Engine.presto925, Browser.Platform.ipod, Browser.Engine.webkit419],
	},
	initialize: function (a) {
		if (this.options.restrictedBrowsers.contains(true)) {
			return
		}
		this.setOptions(a);
		this.mooScrollAreas = [];
		this.windowFxScroll = new Fx.Scroll(document.window, {
			wait: false
		});
		$(document.body).getElements(this.options.selector).each(function (c, b) {
			var d = new MooScrollArea(this.options, c, this.windowFxScroll);
			this.mooScrollAreas.include(d);
			if (this.options.smoothMooScroll.toAnchor || this.options.smoothMooScroll.toMooScrollArea) {
				this.smoothMooScroll = new SmoothMooScroll({
					toAnchor: this.options.smoothMooScroll.toAnchor,
					toMooScrollArea: this.options.smoothMooScroll.toMooScrollArea
				}, d.contentEl, this.windowFxScroll)
			}
		}.bind(this))
	},
	loadContent: function (a) {
		this.mooScrollAreas.each(function (c, b) {
			c.loadContent(a)
		})
	},
	refresh: function () {
		this.mooScrollAreas.each(function (b, a) {
			b.refresh()
		})
	},
	setSlider: function (a) {
		this.mooScrollAreas.each(function (c, b) {
			c.setSlider(a)
		})
	}
});

var MooScrollArea = new Class({
	Implements: [Options, Events],
	initialize: function (a, b, c) {
		this.windowFxScroll = c;
		this.setOptions(a);
		this.parentEl = b.setProperty("rel", "MooScrollArea");
		this.viewPort = {
			x: $(window).getSize().x,
			y: $(window).getSize().y
		};
		this.parentElPadding = this.parentEl.getStyles("padding-top", "padding-right", "padding-bottom", "padding-left");
		this.paddingHeight = parseFloat(this.parentEl.getStyle("padding-top")) + parseFloat(this.parentEl.getStyle("padding-bottom"));
		this.paddingWidth = parseFloat(this.parentEl.getStyle("padding-left")) + parseFloat(this.parentEl.getStyle("padding-right"));
		this.contentEl = new Element("div", {
			"class": "contentEl"
		}).adopt(this.parentEl.getChildren()).inject(this.parentEl, "top");
		this.parentEl.setStyle("overflow", "hidden").setStyles({
			padding: 0,
			width: parseFloat(this.parentEl.getStyle("width")) + this.paddingWidth,
			height: parseFloat(this.parentEl.getStyle("height")) + this.paddingHeight
		});
		this.borderHeight = parseFloat(this.parentEl.getStyle("border-top-width")) + parseFloat(this.parentEl.getStyle("border-bottom-width"));
		this.contentEl.setStyles({
			height: this.parentEl.getSize().y - this.borderHeight,
			overflow: "hidden",
			padding: 0
		});
		this.paddingEl = new Element("div", {
			"class": "paddingEl"
		}).adopt(this.contentEl.getChildren()).inject(this.contentEl, "top").setStyles(this.parentElPadding);
		if (this.options.fullWindowMode) {
			$(document).getElement("html").setStyle("overflow", "hidden");
			this.parentEl.setStyles({
				height: "100%",
				width: "100%",
				position: "absolute"
			});
			this.contentEl.setStyles({
				height: "100%",
				width: "100%",
				position: "absolute"
			})
		}
		this.scrollControlsYWrapper = new Element("div", {
			"class": this.options.scrollControlsYClass
		}).inject(this.parentEl, "bottom");
		this.upBtn = new Element("div", {
			"class": this.options.upBtnClass,
			"html": "^"
		}).inject(this.scrollControlsYWrapper, "bottom");
		this.downBtn = new Element("div", {
			"class": this.options.downBtnClass,
			"html": "^"
		}).inject(this.scrollControlsYWrapper, "bottom");
		this.scrollBar = new Element("div", {
			"class": this.options.scrollBarClass
		}).inject(this.scrollControlsYWrapper, "bottom");
		this.scrollHandle = new Element("div", {
			"class": this.options.scrollHandleClass
		}).inject(this.scrollBar, "inside");
		this.scrollHandleTop = new Element("div", {
			"class": this.options.scrollHandleTopClass
		}).inject(this.scrollHandle, "inside");
		this.scrollHandleBG = new Element("div", {
			"class": this.options.scrollHandleBGClass
		}).inject(this.scrollHandle, "inside");
		this.scrollHandleMiddle = new Element("div", {
			"class": this.options.scrollHandleMiddleClass
		}).inject(this.scrollHandle, "inside");
		this.scrollHandleBottom = new Element("div", {
			"class": this.options.scrollHandleBottomClass
		}).inject(this.scrollHandle, "inside");
		this.coverUp = new Element("div").inject(this.scrollControlsYWrapper, "bottom");
		this.fixIE6CSSbugs();
		this.overHang = this.paddingEl.getSize().y - this.parentEl.getSize().y;
		this.setHandleHeight();
		if (this.overHang <= 0) {
			this.greyOut();
			return
		}
		this.initSlider();
		this.parentEl.addEvents({
			mousewheel: function (d) {
				d = new Event(d).stop();
				if (d.wheel > 0) {
					this.scrollUp(true)
				} else {
					if (d.wheel < 0) {
						this.scrollDown(true)
					}
				}
			}.bind(this),
			keydown: function (d) {
				if (d.key === "up") {
					d = new Event(d).stop();
					this.scrollUp(true)
				} else {
					if (d.key === "down" || d.key === "space") {
						d = new Event(d).stop();
						this.scrollDown(true)
					}
				}
			}.bind(this),
			click: function (d) {
				this.hasFocus = true;
				this.hasFocusTimeout = (function () {
					$clear(this.hasFocusTimeout);
					this.hasFocus = true
				}.bind(this)).delay(50)
			}.bind(this)
		});
		this.contentEl.addEvents({
			scroll: function (d) {
				this.slider.set(this.contentEl.getScroll().y)
			}.bind(this)
		});
		this.scrollHandle.addEvents({
			mousedown: function (d) {
				this.scrollHandle.addClass(this.options.scrollHandleClass + "-Active").setStyle("opacity", this.options.handleActiveOpacity)
			}.bind(this)
		});
		document.addEvents({
			mouseup: function (d) {
				this.scrollHandle.removeClass(this.options.scrollHandleClass + "-Active").setStyle("opacity", this.options.handleOpacity);
				this.upBtn.removeClass(this.options.upBtnClass + "-Active");
				this.downBtn.removeClass(this.options.downBtnClass + "-Active")
			}.bind(this),
			keydown: function (d) {
				if ((this.hasFocus || this.options.fullWindowMode) && (d.key === "down" || d.key === "space" || d.key === "up")) {
					this.parentEl.fireEvent("keydown", d)
				}
			}.bind(this),
			click: function (d) {
				this.hasFocus = false
			}.bind(this)
		});
		window.addEvent("resize", function () {
			$clear(this.refreshTimeout);
			if (this.options.fullWindowMode) {
				this.refreshTimeout = (function () {
					$clear(this.refreshTimeout);
					if (this.viewPort.x != $(window).getSize().x || this.viewPort.y != $(window).getSize().y) {
						this.refresh();
						this.viewPort.x = $(window).getSize().x;
						this.viewPort.y = $(window).getSize().y
					}
				}.bind(this)).delay(250)
			}
		}.bind(this));
		this.upBtn.addEvents({
			mousedown: function (d) {
				$clear(this.upInterval);
				$clear(this.downInterval);
				this.upInterval = this.scrollUp.periodical(10, this);
				this.upBtn.addClass(this.options.upBtnClass + "-Active")
			}.bind(this),
			mouseup: function (d) {
				$clear(this.upInterval);
				$clear(this.downInterval)
			}.bind(this),
			mouseout: function (d) {
				$clear(this.upInterval);
				$clear(this.downInterval)
			}.bind(this)
		});
		this.downBtn.addEvents({
			mousedown: function (d) {
				$clear(this.upInterval);
				$clear(this.downInterval);
				this.downInterval = this.scrollDown.periodical(10, this);
				this.downBtn.addClass(this.options.downBtnClass + "-Active")
			}.bind(this),
			mouseup: function (d) {
				$clear(this.upInterval);
				$clear(this.downInterval)
			}.bind(this),
			mouseout: function (d) {
				$clear(this.upInterval);
				$clear(this.downInterval)
			}.bind(this)
		})
	},
	initSlider: function () {
		this.slider = new Slider(this.scrollBar, this.scrollHandle, {
			range: [0, Math.round(this.overHang)],
			mode: "vertical",
			onChange: function (a, b) {
				this.contentEl.scrollTo(0, a);
				this.webKitKludge(a)
			}.bind(this)
		}).set(0)
	},
	webKitKludge: function (a) {
		//if (!Browser.Engine.webkit) {
			return
		//}
		if (this.step > a) {
			this.step = a;
			return
		}
		$clear(this.sliderTimeout);
		this.sliderTimeout = (function () {
			$clear(this.sliderTimeout);
			var b = (1 * this.paddingEl.getSize().y) / 100;
			if ((b + a) >= this.overHang) {
				if (this.paddingElTopMargin == null) {
					this.paddingElTopMargin = parseFloat(this.paddingEl.getStyle("margin-top"))
				}
				this.paddingEl.setStyle("margin-top", this.paddingElTopMargin - b);
				if (!this.scrollHandleTopMargin) {
					this.scrollHandleTopMargin = parseFloat(this.scrollHandle.getStyle("margin-top"))
				}
				this.scrollHandle.setStyle("margin-top", this.scrollHandleTopMargin + 2);
				this.contentEl.scrollTo(0, this.overHang);
				this.step = this.overHang
			} else {
				this.paddingEl.setStyle("margin-top", this.paddingElTopMargin);
				this.scrollHandle.setStyle("margin-top", this.scrollHandleTopMargin);
				this.contentEl.scrollTo(0, a);
				this.step = a
			}
		}.bind(this)).delay(10)
	},
	scrollUp: function (a) {
		var b = this.contentEl.getScroll().y - 30;
		this.slider.set(b);
		if (this.contentEl.getScroll().y <= 0 && a) {
			document.window.scrollTo(0, document.window.getScroll().y - this.options.increment)
		}
	},
	scrollDown: function (c) {
		var d = this.contentEl.getScroll().y + this.options.increment;
		this.slider.set(d);
		var a = (1 * this.paddingEl.getSize().y) / 100;
		var b = (this.paddingEl.getSize().y - this.parentEl.getSize().y) <= (this.contentEl.getScroll().y + a);
		if (b && c) {
			document.window.scrollTo(0, document.window.getScroll().y + this.options.increment)
		}
	},
	fixIE6CSSbugs: function () {
		if (Browser.Engine.trident4) {
			this.parentEl.setStyle("height", this.parentEl.getStyle("height"));
			this.contentEl.setStyle("height", this.parentEl.getStyle("height"));
			var c = this.scrollBar.getStyle("top").toInt();
			var a = this.scrollBar.getStyle("bottom").toInt();
			var b = this.parentEl.getSize().y - this.borderHeight;
			this.scrollControlsYWrapper.setStyles({
				height: b
			});
			this.scrollBar.setStyles({
				height: b - c - a
			})
		}
	},
	setHandleHeight: function () {
		var a = (100 - ((this.overHang * 100) / this.paddingEl.getSize().y));
		this.handleHeight = ((a * this.parentEl.getSize().y) / 100) - (this.scrollHandleTop.getSize().y + this.scrollHandleBottom.getSize().y);
		if ((this.handleHeight + this.scrollHandleTop.getSize().y + this.scrollHandleBottom.getSize().y) >= this.scrollBar.getSize().y) {
			this.handleHeight -= (this.scrollHandleTop.getSize().y + this.scrollHandleBottom.getSize().y) * 2
		}
		if (this.scrollHandle.getStyle("min-height") && this.handleHeight < parseFloat(this.scrollHandle.getStyle("min-height"))) {
			this.handleHeight = parseFloat(this.scrollHandle.getStyle("min-height")) + this.scrollHandleBottom.getSize().y + this.scrollHandleTop.getSize().y
		}
		this.scrollHandle.setStyles({
			height: this.handleHeight
		})
	},
	greyOut: function () {
		this.scrollHandle.setStyles({
			display: "none"
		});
		this.upBtn.setStyles({
			opacity: this.options.disabledOpacity
		});
		this.scrollControlsYWrapper.setStyles({
			opacity: this.options.disabledOpacity
		});
		this.downBtn.setStyles({
			opacity: this.options.disabledOpacity
		});
		this.scrollBar.setStyles({
			opacity: this.options.disabledOpacity
		});
		this.coverUp.setStyles({
			display: "block",
			position: "absolute",
			background: "white",
			opacity: 0.01,
			right: "0",
			top: "0",
			width: "100%",
			height: this.scrollControlsYWrapper.getSize().y
		})
	},
	unGrey: function () {
		this.scrollHandle.setStyles({
			display: "block",
			height: "auto"
		});
		this.scrollControlsYWrapper.setStyles({
			opacity: 1
		});
		this.upBtn.setStyles({
			opacity: 1
		});
		this.downBtn.setStyles({
			opacity: 1
		});
		this.scrollBar.setStyles({
			opacity: 1
		});
		this.coverUp.setStyles({
			display: "none",
			width: 0,
			height: 0
		});
		this.setHandleHeight();
	},
	loadContent: function (a) {
		this.slider.set(0);
		this.paddingEl.empty().set("html", a);
		this.refresh();
	},
	refresh: function () {
		var a = Math.round(((100 * this.step) / this.overHang));
		if (this.options.fullWindowMode) {
			var b = $(window).getSize();
			this.parentEl.setStyles({
				width: "100%",
				height: "100%"
			})
		}
		this.fixIE6CSSbugs();
		this.overHang = this.paddingEl.getSize().y - this.parentEl.getSize().y;
		this.setHandleHeight();
		if (this.overHang <= 0) {
			this.greyOut();
			return
		} else {
			this.unGrey()
		}
		this.scrollHandle.removeEvents();
		var c = Math.round((a * this.overHang) / 100);
		this.initSlider();
		this.slider.set(c);
		if (Browser.Engine.trident4) {
			this.scrollHandleBG.setStyle("height", "0").setStyle("height", "100%")
		}
		if (this.options.smoothMooScroll.toAnchor || this.options.smoothMooScroll.toMooScrollArea) {
			this.smoothMooScroll = new SmoothMooScroll({
				toAnchor: this.options.smoothMooScroll.toAnchor,
				toMooScrollArea: this.options.smoothMooScroll.toMooScrollArea
			}, this.contentEl, this.windowFxScroll)
		}
	},
	setSlider: function (a) {
		if (a == "top") {
			this.slider.set(0)
		} else {
			if (a == "bottom") {
				this.slider.set("100%")
			} else {
				this.slider.set(a)
			}
		}
	}
});

var SmoothMooScroll = new Class({
	Extends: Fx.Scroll,
	initialize: function (b, c, d) {
		this.setOptions(b);
		this.windowFxScroll = d;
		this.context = c;
		c = c || document;
		this.context = c;
		var f = c.getDocument(),
			e = c.getWindow();
		this.parent(c, b);
		this.links = (this.options.links) ? $$(this.options.links) : $$(f.links);
		var a = e.location.href.match(/^[^#]*/)[0] + "#";
		this.links.each(function (h) {
			if (h.href.indexOf(a) != 0) {
				return
			}
			var g = h.href.substr(a.length);
			if (g && $(g) && $(g).getParents().contains($(this.context))) {
				this.useLink(h, g, true)
			} else {
				if (g && $(g) && !this.inMooScrollArea($(g))) {
					this.useLink(h, g, false)
				}
			}
		}, this);
		if (!Browser.Engine.webkit419) {
			this.addEvent("complete", function () {
				e.location.hash = this.anchor
			}, true)
		}
	},
	inMooScrollArea: function (a) {
		return a.getParents().filter(function (c, b) {
			return c.match("[rel=MooScrollArea]")
		}).length > 0
	},
	putAnchorInAddressBar: function (a) {
		window.location.href = "#" + a
	},
	useLink: function (b, a, c) {
		b.removeEvents("click");
		b.addEvent("click", function (d) {
			if (!a || !$(a)) {
				return
			}
			this.anchor = a;
			if (c) {
				if (this.options.toMooScrollArea && this.options.toAnchor) {
					this.windowFxScroll.toElement(this.context.getParent()).chain(function (f, e) {
						this.toElement(a).chain(function () {
							this.putAnchorInAddressBar(a)
						}.bind(this))
					}.bind(this))
				} else {
					if (this.options.toMooScrollArea) {
						this.windowFxScroll.toElement(this.context.getParent()).chain(function () {
							this.putAnchorInAddressBar(a)
						}.bind(this))
					} else {
						if (this.options.toAnchor) {
							this.toElement(a).chain(function () {
								this.putAnchorInAddressBar(a)
							}.bind(this))
						}
					}
				}
			} else {
				this.windowFxScroll.toElement(a).chain(function () {
					this.putAnchorInAddressBar(a)
				}.bind(this))
			}
			d.stop()
		}.bind(this))
	}
});
