Cufon.replace('div.yes, div.no')
Event.observe(document, 'dom:loaded', function(){
	if (!this.initialized) {
		this.initialized = true
		Browser.init()
		Cufon.now()
		VDAgeVerification.init()
		// CommentsForm.init()
	}
	CheckDomain.init()
})

var Browser = {
	init: function(){
		var classNames = $$('html')[0].classNames()
		$w('win linux mac freebsd ipod iphone webtv mobile ie ie8 ie7 ie6 ie5 gecko ff2 ff3 ff3_5 opera opera8 opera9 opera10 konqueror webkit safari safari3 chrome iron').each(function(s){
			if (classNames.include(s)) {
				this[s] = true
			}
		}.bind(this))
	}
}

var CheckDomain = {
	init: function(){
		if (window.location.host == 'veda-night.ru' || window.location.host == 'http://veda-night.ru' || window.location.host == 'www.veda-night.ru') {
			VDBar.click('time', 'night')
		} else {
			VDBar.click('time', 'day')
		}
	}
}

Number.prototype.roundToPrecision = function(precision){
	return Math.round(this / precision) * precision
}
String.prototype.toI = function(radix){
	return parseInt(this, radix || 10)
}

function vdFlashOnLoad(id){ VDFlash.onLoad(id) }
function vdFlashOnPlay(id){ VDFlash.onPlay(id) }
var VDFlash = {
	onLoad: function(id){
		var node = $(Browser.ie ? window[id] : id)
		try {
			node.api_addEventListener('onPlay', 'vdFlashOnPlay')
		} catch(e) {}
	}
	, onPlay: function(id){
		$$('object, embed').each(function(node){
			if (node.id != id && node.name != id) {
				try {
					node.api_pause()
				} catch(e) {}
			}
		})
	}
}

Element.addMethods({
	observeClick: function(element, handler){
		element.observe('mousedown', Event.stop)
		return element.observe('click', handler)
	}
	, getInnerText: function(element){
		return element.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, ' ')
	}
})

var VDAgeVerification = {
	init: function(){
		this.ageVerification = $('age_verification')
		this.cookieJar = new CookieJar
		if (this.cookieJar.get('age_verified') != null) {
			this.onAgeVerified()
		} else {
			this.ageVerification.show()
			if (this.ageVerification) {
				this.yes = this.ageVerification.down('.yes')
				this.yes.observeClick(this.onAgeVerified.bind(this))
			}
			VDFuckingAdCode.insert('main')
		}
	}
	, onAgeVerified: function(){
		this.cookieJar.put('age_verified', true)
		this.ageVerification.hide()

		VDRotator.init() // don't put insed following show/hide or vml will not work
		this.toShow = $('body')
		this.toShow.setStyle({visibility:'hidden'})
		this.toShow.show()
		$A([VDGallery, VDFloatingPage, VDEvent, VDOrangeLine, VDBar]).invoke('init')
		VDRotator.initialSwap()
		VDAnchorWatcher.init()
		this.toShow.hide()
		this.toShow.setStyle({visibility:''})
		this.toShow.appear({duration:0.5})
	}
}

var VDRotator = {
	init: function(){
		if (this.container = $('rotating_image')) {
			this.body = this.container.up('body')
			this.bodyNightStyle = 'background-color: #000014'
			this.bodyDayStyle = 'background-color: #e4f4fe'
			this.image = this.container.down('div.image')
			this.imageNormal = this.image.down('div.normal')
			this.imageRevert = this.image.down('div.revert')
			this.imageBlurred = this.image.down('div.blurred')
			this.imageHighlight = this.image.down('div.highlight')
			this.canvas = this.container.down('canvas')
			this.slop = $('slop')
			this.slopDay = this.slop.down('.slop_day')
			this.slopNight = this.slop.down('.slop_night')
			this.rotateButtons = $('rotate_buttons')
			this.adLinks = $('adLinks')
			this.rotateButtonDay = $('rotate_button_day')
			this.rotateButtonNight = $('rotate_button_night')

			this.swap = this.swap.bind(this)
			this.swapToDay = this.swapToDay.bind(this)
			this.swapToNight = this.swapToNight.bind(this)

			this.canRotate = true
			this.rotateButtonDay.observeClick(function(){ VDBar.click('time', 'day') })
			this.rotateButtonNight.observeClick(function(){ VDBar.click('time', 'night') })

			this.audioDay = $('audio_day')
			this.audioNight = $('audio_night')

			this.initDrawFunction()
		}
	}
	, rotating: function(){
		return this.effect && this.effect.state != 'finished'
	}
	, swapToDay: function(){
		if (this.angle == 0) {
			this.swap()
			VDFuckingAdCode.insert('day')
		}
	}
	, swapToNight: function(){
		if (this.angle == 180) {
			this.swap()
			VDFuckingAdCode.insert('night')
		}
	}
	, initialSwap: function(){
		var hours = new Date().getHours()
		if (hours >= 21 || hours <= 6) {
			this.angle = 0
			this.adLinks.addClassName('nightAdLinks')
		} else {
			this.angle = 180
			VDOrangeLine.initialSwap()
			VDEvent.initialSwap()
			this.slopDay.show(), this.slopNight.hide()
			this.audioDay.show(), this.audioNight.hide()
			this.rotateButtonNight.show(), this.rotateButtonDay.hide()
			this.body.setStyle(this.bodyDayStyle)
			VDBar.makePressed(['time', 'button_day'])
		}
		this.draw()
		VDFuckingAdCode.insert(this.angle < 180 ? 'night' : 'day')
	}
	, swap: function(){
		if (!this.rotating()) {
			var durationHide = 0.2, durationRotate = 2

			VDOrangeLine.swap({duration:durationHide, wait:durationRotate})
			VDEvent.swap({duration:durationHide, wait:durationRotate})

			new Effect.Fade(this.slop, {from:1, to:0, duration:durationHide, afterFinish:function(){
				if (this.angle < 180) {
					this.slopDay.show(), this.slopNight.hide()
					this.audioDay.show(), this.audioNight.hide()
				} else {
					this.slopDay.hide(), this.slopNight.show()
					this.audioDay.hide(), this.audioNight.show()
				}
			}.bind(this)})
			new Effect.Appear(this.slop, {from:0, to:1, duration:durationHide, delay:durationRotate + durationHide})
			new Effect.Fade(this.adLinks, {from:1, to:0, duration:durationHide})
			new Effect.Fade(this.rotateButtons, {from:1, to:0, duration:durationHide, afterFinish:function(){
				if (this.angle < 180) {
					this.rotateButtonNight.show(), this.rotateButtonDay.hide()
					this.adLinks.removeClassName('nightAdLinks')
				} else {
					this.rotateButtonNight.hide(), this.rotateButtonDay.show()
					this.adLinks.addClassName('nightAdLinks')
				}
			}.bind(this)})
			new Effect.Appear(this.rotateButtons, {from:0, to:1, duration:durationHide, delay:durationRotate + durationHide})
			new Effect.Appear(this.adLinks, {from:0, to:1, duration:durationHide, delay:durationRotate + durationHide})
			new Effect.Morph(this.body, {style: this.angle < 180 ? this.bodyDayStyle : this.bodyNightStyle, delay: durationHide + durationHide * 3, duration: durationRotate - durationHide * 3 * 2})
			this.effect = new Effect.Tween(this, this.angle, this.angle < 180 ? 180 : 360, {delay: durationHide, duration:durationRotate, transition:Effect.Transitions.Cubic.easeInOut}, this.step)
		}
	}
	, step: function(angle){
		if (angle != undefined) {
			this.angle = (angle + 360) % 360
		}
		this.draw()
	}
	, invert: function(){
		return this.angle > 90 && this.angle < 270
	}
	, radians: function(){
		return this.angle * Math.PI / 180
	}
	, draw: function(){
		var center = 1 - (this.angle % 180 - 90).abs() / 90
		var blurredOpacity = [(center - 0.05) * 5, 0].max()
		var highlightOpacity = [(center - 0.5), 0].max() * 2

		this.imageHighlight.setOpacity(highlightOpacity)

		this.drawRotate(blurredOpacity)
	}
	, initDrawFunction: function(){
		this.imageHighlight.setOpacity(0)
		this.imageHighlight.show()
		if (this.image.filters) {
			this.imageNormal.hide()

			document.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)")
			try {
				!document.namespaces.rvml && document.namespaces.add("rvml", "urn:schemas-microsoft-com:vml")
				var createNode = function(tagName){ return document.createElement('<rvml:' + tagName + ' class="rvml">') }
			} catch(e) {
				var createNode = function(tagName){ return document.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">') }
			}

			this.vmlImage = $(createNode('group'))
			this.vmlImageNormal = $(createNode('image'))
			this.vmlImageRevert = $(createNode('image'))
			this.vmlImageBlurred = $(createNode('image'))
			$A([this.vmlImage, this.vmlImageNormal, this.vmlImageBlurred]).invoke('setStyle', {position:'absolute', width:'1796px', height:'2361px', top:0, left:0})
			this.vmlImage.coordsize = '1796,2361'
			this.vmlImageNormal.src = "/images/rotate/day-night-normal.jpg"
			this.vmlImageRevert.src = "/images/rotate/day-night-revert.jpg"
			this.vmlImageBlurred.src = "/images/rotate/day-night-blurred.jpg"
			this.vmlImage.appendChild(this.vmlImageNormal)
			this.vmlImage.appendChild(this.vmlImageBlurred)
			this.image.appendChild(this.vmlImage)

			this.drawRotate = function(blurredOpacity){
				var angle = this.angle.round()
				this.vmlImage.style.rotation = this.invert() ? 180 - angle : angle
				this.vmlImage.style.flip = this.invert() ? 'y' : ''
				if (blurredOpacity > 0) {
					this.vmlImageBlurred.show()
				} else {
					this.vmlImageBlurred.hide()
				}
				if (this.angle == 180) {
					this.imageRevert.show()
					this.vmlImage.hide()
				} else {
					this.vmlImage.show()
					this.imageRevert.hide()
				}
			}
		} else if (this.image.style.WebkitTransform != undefined || this.image.style.MozTransform != undefined || this.image.style.transform != undefined) {
			this.imageBlurred.setOpacity(0)
			this.imageBlurred.show()
			this.drawRotate = function(blurredOpacity){
				this.imageBlurred.setOpacity(blurredOpacity)

				var m = new Matrix2D().rotate(this.radians()), styleMatrix
				if (this.invert()) {
					m = m.scale(-1, 1)
				}

				if (this.angle == 0) {
					styleMatrix = 'matrix(1,0,0,1,0,0)'
				} else if (this.angle == 180) {
					styleMatrix = 'matrix(1,0,0,-1,0,0)'
				} else {
					styleMatrix = 'matrix(' +  [m.xx, m.yx, m.xy, m.yy, 0, 0].invoke('roundToPrecision', 0.0001).join(',')  + ')'
				}
				this.image.style.WebkitTransform = this.image.style.MozTransform = this.image.style.rotation = styleMatrix
			}
		} else {
			this.imageNormal.hide()
			this.canvas.show()
			this.imageNode = new Image()
			this.imageNode.src = "/images/rotate/day-night-normal.jpg?1265722119"
			this.drawRotate = function(){
				var ctx = this.canvas.getContext('2d')
				ctx.clearRect(0, 0, 1796, 2361)
				ctx.save()
				ctx.translate(898, 1180)
				ctx.rotate(this.radians())
				ctx.translate(-898, -1180)
				if (this.invert()) {
					ctx.translate(898, 1180)
					ctx.scale(-1, 1)
					ctx.translate(-898, -1180)
				}
				ctx.drawImage(this.imageNode, 0, 0)
				ctx.restore()
			}
		}
	}
}

var VDEvent = Class.create({
	initialize: function(element) {
		var height, color
		this.element = element
		this.li = this.element.up('li')
		this.excerpt = this.element.down('div.excerpt')
		this.state = 'closed'
		this.highlighting = false
		this.parent = this.element.up('ul')

		this.toggle = this.toggle.bind(this)

		this.allClosedTop = this.top()
		this.time = this.element.down('div.time_container')
		this.timeValues = this.time.readAttribute('rel').split(':').invoke('toI')
		height = this.time.getStyle('height').toI()
		color = this.time.getStyle('color')
		this.timeStyleMin = 'top:-' + height + 'px; height:' + height + 'px; color: ' + color + ';'
		height = this.time.getStyle('font-size').toI() * 0.8
		this.timeStyleMax = 'top:-' + height + 'px; height:' + height + 'px; color: #ff4e00; cursor: pointer'
		this.time.observeClick(this.toggle)
		this.time.observe('mouseover', function(){ this.highlight() }.bind(this))
		this.time.observe('mouseout', function(){ this.deHighlight() }.bind(this))

		if (this.image = this.element.down('div.image')) {
			var img = this.image.down('img')
			height = this.image.getStyle('height').toI()
			this.imageStyleMin = 'top:-' + height + 'px; height:' + height + 'px;'
			height = img ? img.height : height
			this.imageStyleMax = 'top:-' + height + 'px; height:' + height + 'px;'
			this.image.observeClick(this.toggle)
			this.image.observe('mouseover', function(){ this.highlight() }.bind(this))
			this.image.observe('mouseout', function(){ this.deHighlight() }.bind(this))
		}

		this.textual = this.element.down('div.textual')
		this.textualStyleMin = 'color: ' + this.textual.getStyle('color') + ';'
		this.textualStyleMax = 'color: #000;'

		this.floatingPageId = this.element.readAttribute('rel')

		this.anchor = this.element.down('div.anchor').readAttribute('rel')
	}
	, highlightDuration: 0.2
	, highlight: function(persist){
		this.persistHiglighted = this.persistHiglighted || persist
		if (!this.highlighting && this.state == 'closed') {
			VDEvent.deHighlightExcept(this, persist)

			this.highlighting = true
			this.time.up('li').addClassName('activeEvent')
			this.runEffects('highlighting', [
				new Effect.Morph(this.time, {style:this.timeStyleMax, duration: this.highlightDuration, afterUpdate: function(){ VDEvent.refreshTimeFont() }}),
				this.image ? new Effect.Morph(this.image, {style:this.imageStyleMax, duration: this.highlightDuration}) : null
			])
		}
	}
	, deHighlight: function(persist){
		if (this.highlighting && this.state == 'closed') {
			if (this.persistHiglighted == persist) {
				this.persistHiglighted = undefined
				this.highlighting = false
				this.time.up('li').removeClassName('activeEvent')
				this.runEffects('highlighting', [
					new Effect.Morph(this.time, {style:this.timeStyleMin, duration: this.highlightDuration, afterUpdate: function(){ VDEvent.refreshTimeFont() }}),
					this.image ? new Effect.Morph(this.image, {style:this.imageStyleMin, duration: this.highlightDuration}) : null
				])
			}
		}
	}
	, toggle: function(){
		if (!$w('opened opening').include(this.state)) {
			this.open()
		} else {
			this.close()
		}
	}
	, open: function(){
		if (this.needOpen()) {
			VDFloatingPage.show(this.floatingPageId)
		}
	}
	, close: function(){
		VDFloatingPage.hide()
	}
	, needOpen: function(){
		return !$w('opened opening').include(this.state)
	}
	, runEffects: function(name, effects){
		if (this.effects == undefined) {
			this.effects = {}
		}
		if (this.effects[name] != undefined) {
			this.effects[name].invoke('cancel')
		}
		this.effects[name] = effects.compact()
	}
	, top: function(){
		return this.li.positionedOffset().top
	}
})
Object.extend(VDEvent, {
	init: function(){
		this.objects = $$('div.events').map(function(container){
			var o
			container.setStyle({visibility:'hidden'})
			container.show()
			var viewportHeight = document.viewport.getHeight()
			container.setStyle({paddingTop:viewportHeight / 2 + 'px'})
			var dimensions = container.getDimensions()
			o = {
				height: dimensions.height,
				closedMargin: dimensions.height - 1280,
				container:container,
				events:container.select('div.event').map(function(eventElement){ return new VDEvent(eventElement) })
			}
			container.setStyle({position:'absolute', bottom:'0', left:'50%', marginLeft:-dimensions.width / 2 + 'px'})
			container.hide()
			container.setStyle({visibility:''})
			return o
		})
		this.minAllClosedTop = this.events().pluck('allClosedTop').min()
		this.extendTopNode = $$('div.body')[0]
		this.swapContainer(true)
	}
	, minHeight: function(){
		return this.objects[this.active].closedMargin
	}
	, shrinkTop: function(){
		this.setTop(this.minHeight())
	}
	, documentUnextendedHeight: function(){
		return this.extendTopNode.getHeight()
	}
	, documentHeight: function(){
		return this.extendTopNode.getHeight() + this.extendTopNode.getStyle('margin-top').toI()
	}
	, extendTop: function(full){
		var viewportHeight = document.viewport.getHeight()
		this.setTop(full - this.documentUnextendedHeight() + viewportHeight / 2)
	}
	, setTop: function(top){
		top = [top, this.minHeight()].max()
		var viewportScroll = document.viewport.getScrollOffsets()
		VDFloatingPage.setTop(-top)
		this.extendTopNode.setStyle({marginTop:top + 'px'})
		this.lastTop = top
	}
	, swapContainer: function(setVisibility){
		if (this.active == undefined) {
			this.active = 0
		} else {
			if (setVisibility && this.objects[this.active]) {
				this.objects[this.active].container.hide()
			}
			this.active = (this.active + 1) % this.objects.length
		}
		if (this.objects[this.active]) {
			this.shrinkTop()
			if (setVisibility) {
				this.objects[this.active].container.show()
			}
		}
	}
	, events: function(){
		return this.objects[this.active] ? this.objects[this.active].events : []
	}
	, height: function(){
		return this.objects[this.active] ? this.objects[this.active].height : 0
	}
	, deHighlight: function(persist){
		this.events().invoke('deHighlight', persist)
	}
	, deHighlightExcept: function(except, persist){
		this.events().without(except).invoke('deHighlight', persist)
	}
	, tops: function(){
		return this.events().invoke('top')
	}
	, allClosedTops: function(){
		return this.events().pluck('allClosedTops')
	}
	, initialSwap: function(){
		if (this.objects[this.active]) {
			this.objects[this.active].container.hide()
			this.swapContainer(false)
			this.objects[this.active].container.show()
		}
	}
	, swap: function(o){
		if (this.objects[this.active]) {
			new Effect.Fade(this.objects[this.active].container, {from:1, to:0, duration:o.duration})
			this.swapContainer(false)
			new Effect.Appear(this.objects[this.active].container, {from:0, to:1, duration:o.duration, delay:o.wait + o.duration, afterFinish:function(){
				if (this.openAfterRotate) {
					if (this.objects[this.active].events.include(this.openAfterRotate)) {
						this.openAfterRotate.open()
					}
					this.openAfterRotate = undefined
				}
			}.bind(this)})
		}
	}
	, refreshTimeFont: function(){
		Cufon.replace('div.events div.event div.excerpt div.time_container')
	}
	, open: function(anchor){
		var open_object, open_event
		this.objects.each(function(object){
			object.events.each(function(event){
				if (event.anchor == anchor) {
					open_object = object
					open_event = event
				}
			}.bind(this))
		}.bind(this))
		if (open_object && open_event) {
			if (open_object == this.objects[this.active]) {
				open_event.open()
			} else {
				this.openAfterRotate = open_event
				VDBar.click('time', open_object.container.readAttribute('rel'))
			}
		}
	}
})
VDEvent.refreshTimeFont()

var VDOrangeLine = {
	init: function(){
		if (this.orangeLine = $('orange_line')) {
			this.currentTime = this.orangeLine.down('div.current_time')
			this.currentTime.show()

			var numberNodes = this.currentTime.select('div.number')
			this.numberDimensions = numberNodes[0].getDimensions()
			this.numberStates = numberNodes.map(function(numberNode){
				return {node:numberNode.down(), value:0, transition:0}
			})

			this.date = undefined
			this.moveLine()

			Event.observe(document, 'mousemove', this.saveMousePosition.bind(this))
			Event.observe(window, 'resize', this.fixBoundTop.bind(this))
			Event.observe(document, 'mousewheel', this.stopScroll.bindAsEventListener(this))
			Event.observe(document, 'DOMMouseScroll', this.stopScroll.bindAsEventListener(this))
			this.startMoveLineInterval()
		}
	}
	, startMoveLineInterval: function(){
		this.stopMoveLineInterval()
		this.moveLineInterval = setInterval(this.moveLine.bind(this), 50)
	}
	, stopMoveLineInterval: function(){
		clearInterval(this.moveLineInterval)
	}
	, moveLine: function(force){
		var viewportHeight = document.viewport.getHeight()
		var viewportScroll = document.viewport.getScrollOffsets()
		var lineTop = viewportHeight / 2 + viewportScroll.top

		if (force || lineTop != this.previousLineTop) {
			this.previousLineTop = this.previousLineTop || 0
			var direction = lineTop > this.previousLineTop ? 1 : -1
			this.previousLineTop = lineTop
			var elementTops = VDEvent.tops()
			var snap = Browser.ie ? undefined : elementTops.detect(function(elementTop){ return $R(-90, 60).include(lineTop - elementTop) })
			if (snap == undefined) {
				this.stopScroll()
				var elementTops = VDEvent.tops()
				if (elementTops.all(function(n){ return n == 0 })) {
					elementTops = VDEvent.allClosedTops()
				}
				var elementTopParts = elementTops.partition(function(elementTop){ return elementTop < lineTop })
				var higher = elementTopParts[0].last()
				var lower = elementTopParts[1].first()
				var higherValues, lowerValues
				if (higher && VDEvent.events()) {
					higherValues = VDEvent.events()[elementTops.indexOf(higher)].timeValues
				} else {
					higher = 0
					var firstTimeValues = VDEvent.events().first().timeValues
					higherValues = [firstTimeValues[0] - 3, firstTimeValues[1]]
				}
				if (lower && VDEvent.events()) {
					lowerValues = VDEvent.events()[elementTops.indexOf(lower)].timeValues
				} else {
					lower = VDEvent.documentHeight()
					var lastTimeValues = VDEvent.events().last().timeValues
					lowerValues = [lastTimeValues[0] + 3, lastTimeValues[1]]
				}
				var weight = (lineTop - higher) / ((lower - higher) || 1)
				var time = this.hourMinuteTime(higherValues) * (1 - weight) + this.hourMinuteTime(lowerValues) * weight
				this.updateTime(this.rawValues(new Date(time)), direction)

				VDEvent.deHighlight(true)
			} else {
				if (this.scrollEffect && this.scrollEffect.state == 'idle') {
					this.stopScroll()
				}
				if (!this.scrollEffect || this.scrollEffect.state == 'finished') {
					this.scrollEffect = new Effect.Tween(this, viewportScroll.top, snap - (viewportHeight - 1) / 2, {
						duration: 0.2,
						delay: 0.3,
						transition: Effect.Transitions.sinoidal
					}, function(to){
						window.scrollTo(document.viewport.getScrollOffsets().left, to)
					})
				}

				if (VDEvent.events()) {
					VDEvent.events()[elementTops.indexOf(snap)].highlight(true)
					this.updateTime(VDEvent.events()[elementTops.indexOf(snap)].timeValues, direction)
				}
			}
		}
	}
	, stopScroll: function(){
		if (this.scrollEffect) {
			this.scrollEffect.cancel()
		}
	}
	, hourMinuteTime: function(values){
		var date = new Date(0)
		date.setHours(values[0])
		date.setMinutes(values[1])
		return date.valueOf()
	}
	, saveMousePosition: function(e){
		if (!e) var e = window.event
		if (e.pageY) {
			this.mouseTop = e.pageY
		} else if (e.clientY) {
			this.mouseTop = e.clientY + document.body.scrollTop + document.documentElement.scrollTop
		}
	}
	, rawValues: function(date){
		return [date.getHours(), date.getMinutes()]
	}
	, getValues: function(rawValues){
		return rawValues.invoke('toPaddedString', 2).invoke('split', '').flatten().invoke('toI')
	}
	, updateTime: function(values, direction){
		if (!this.bound) {
			if (!this.date || this.date.inspect() != values.inspect()) {
				var numbers = this.getValues(values)
				this.numberStates.each(function(numberState, i){
					var number = numbers[i] || 0
					var numberWas = numberState.value + numberState.transition
					if (number != numberWas) {
						if (direction < 0) {
							while (number > numberWas) { numberWas += 10 }
						} else {
							while (number < numberWas) { number += 10 }
						}
						var delta = (number - numberWas).abs()
						var transition = Effect.Transitions.sinoidal
						if (numberState.effect && numberState.effect.state != 'finised') {
							numberState.effect.cancel()
							transition = Effect.Transitions.linear
						}
						numberState.effect = new Effect.Tween(this, numberWas, number, {
							duration: [0.3, delta * 0.1].max(),
							transition: transition
						}, this.setNumberStyle.bind(this, numberState))
					}
				}.bind(this))
				this.date = values
			}
		}
	}
	, setNumberStyle: function(state, tween){
		var value = tween.floor()
		state.value = value % 10
		state.transition = tween - value
		var i = ((tween * 11).round()) % 110
		if (state.offset != i) {
			state.offset = i
			var x = i % 11
			var y = (i - x) / 11
			var left = -x * this.numberDimensions.width
			var top = -y * this.numberDimensions.height
			state.node.setStyle({left:left + 'px', top: top + 'px'})
		}
	}
	, initialSwap: function(){
	}
	, swap: function(o){
		if (this.orangeLine) {
			new Effect.Fade(this.orangeLine, {from:1, to:0, duration:o.duration})
			new Effect.Appear(this.orangeLine, {from:0, to:1, duration:o.duration, delay:o.wait + o.duration, beforeUpdate:function(){
				this.moveLine(true)
			}.bind(this)})
		}
	}
	, bindToPosition: function(top, event, options){
		this.stopMoveLineInterval()
		if (this.bindEffect && this.bindEffect.state != 'finised') {
			this.bindEffect.cancel()
		}
		if (this.orangeLine.getStyle('position') != 'absolute') {
			var viewportHeight = document.viewport.getHeight()
			var viewportScroll = document.viewport.getScrollOffsets()
			this.orangeLine.setStyle({position:'absolute', top:viewportHeight / 2 + viewportScroll.top + 'px'})
		}
		this.bindEffect = new Effect.Morph(this.orangeLine, {style:'top:' + top + 'px', duration:options.duration, afterFinish: function(){
			this.updateTime(event.timeValues, 1)
			this.bound = true
		}.bind(this)})
	}
	, unBind: function(options){
		this.startMoveLineInterval()
		if (this.bindEffect && this.bindEffect.state != 'finised') {
			this.bindEffect.cancel()
		}
		if (this.orangeLine.getStyle('position') == 'absolute') {
			var viewportHeight = document.viewport.getHeight()
			var viewportScroll = document.viewport.getScrollOffsets()
			var lineTop = this.orangeLine.positionedOffset().top
			this.orangeLine.setStyle({position:'fixed', top:(lineTop - viewportScroll.top) + 'px'})
		}
		this.bindEffect = new Effect.Morph(this.orangeLine, {style:'top:' + viewportHeight / 2 + 'px', duration:options.duration})
		this.bound = false
	}
	, fixBoundTop: function(){
		if (this.orangeLine.getStyle('position') != 'absolute') {
			if (this.bindEffect && this.bindEffect.state != 'finised') {
				this.bindEffect.cancel()
			}
			var viewportHeight = document.viewport.getHeight()
			this.orangeLine.setStyle({top:viewportHeight / 2 + 'px'})
		}
	}
}

var VDBar = {
	init: function(){
		if (this.bar = $$('div.bar')[0]) {
			this.buttons = {}
			this.bar.select('li.button').each(function(button){
				var rel = button.readAttribute('rel')
				if (this.buttons[rel] == undefined) {
					this.buttons[rel] = $H()
				}
				this.buttons[rel].set(button.id, button)
				button.observeClick(function(e){ this.onClick(e.findElement('li')) }.bindAsEventListener(this))
			}.bind(this))
			this.onClicks = {
				button_day: this.onDayNightClick.bind(this, VDRotator.swapToDay)
				, button_night: this.onDayNightClick.bind(this, VDRotator.swapToNight)
				, button_product: this.onPopupClick
				, button_company: this.onPopupClick
				, button_ads: this.onPopupClick
				, button_download: this.onPopupClick
			}
		}
	}
	, onDayNightClick: function(afterFinish, li){
		if (VDRotator.rotating()) {
			return false
		} else {
			VDFloatingPage.hide()
			VDBar.scrollToBottom(afterFinish)
			return true
		}
	}
	, onPopupClick: function(li){
		var id = li.id.replace(/^button_/, 'page_')
		if (VDFloatingPage.page_exists(id)) {
			VDFloatingPage.show(id)
			return true
		} else {
			return false
		}
	}
	, scrollToBottom: function(afterFinish){
		var viewportScroll = document.viewport.getScrollOffsets()
		var viewportHeight = document.viewport.getHeight()
		var scrollTo = VDEvent.documentHeight() - viewportHeight
		new Effect.Tween(this, viewportScroll.top, scrollTo, {duration: [0.001 * (scrollTo - viewportScroll.top), 0.5].min(), afterFinish:afterFinish}, function(left, top){
			window.scrollTo(left, top)
		}.bind(this, viewportScroll.left))
	}
	, click: function(rel, id){
		var li = this.buttons[rel].get('button_' + id)
		if (li) {
			this.onClick(li)
		}
	}
	, onClick: function(li){
		if (!li.hasClassName('current')) {
			if (this.onClicks[li.id] ? this.onClicks[li.id](li) : true) {
				this.makePressed(li)
			}
		}
	}
	, makePressed: function(li){
		if (Object.isArray(li)) {
			li = this.buttons[li[0]].get(li[1])
		}
		li.addClassName('current')
		this.buttons[li.readAttribute('rel')].values().without(li).invoke('removeClassName', 'current')
	}
	, unPress: function(group){
		this.buttons[group].values().invoke('removeClassName', 'current')
	}
}

var VDGallery = Class.create({
	initialize: function(element) {
		this.gallery = element
		this.ul = this.gallery.down('ul')
		this.lis = this.gallery.select('li')
		this.current = 0
		this.total = this.lis.length

		this.controls = element.down('div.controls')
		this.prev = this.controls.down('.prev')
		this.next = this.controls.down('.next')
		if (this.upText = this.controls.down('.uptext')) {
			this.upTextContent = this.upText.innerHTML
		}
		this.currentNodes = this.gallery.select('.current')
		this.totalNodes = this.gallery.select('.total')
		this.descriptionNodes = this.gallery.select('.description')
		this.totalNodes.invoke('update', this.total)

		this.prev.observeClick(this.switchFrame.bind(this, -1))
		this.next.observeClick(this.switchFrame.bind(this, +1))
		this.ul.observeClick(this.switchFrame.bind(this, +1))
		this.switchFrame(0)
		this.updateCount()
	}
	, switchFrame: function(delta){
		this.current = [this.current + delta, 0].max() % this.total
		this.lis.each(function(li, i){
			if (i == this.current) {
				li.show()
			} else {
				li.hide()
			}
		}.bind(this))
		this.updateCount()
	}
	, updateCount: function(){
		this.currentNodes.invoke('update', this.current + 1)
		var li, img, description, insert
		if (li = this.lis[this.current]) {
			if (img = li.down('img')) {
				description = img.readAttribute('alt')
			}
			if (this.upText && (insert = li.down('div.uptext'))) {
				this.upText.update(this.upTextContent.replace('[insert]', insert.innerHTML))
			}
		}
		this.descriptionNodes.invoke('update', description)
	}
})
Object.extend(VDGallery, {
	init: function(){
		$$('div.gallery').each(function(element){
			if (!element.hasClassName('gallery_initialized')) {
				new VDGallery(element)
				element.addClassName('gallery_initialized')
			}
		})
	}
})

var VDFloatingPage = Class.create({
	initialize: function(element){
		this.element = element
		this.id = element.id
		this.holder = element.down('div.holder')
		this.contentState = 'empty'
	}
	, loadContent: function(){
		if (this.contentState == 'empty') {
			this.holder.update(VDFloatingPage.data.get(this.id))
			this.holder.show()
			this.contentState = 'loaded'
		}
	}
	, unloadContentInIe: function(){
		if (Browser.ie) {
			this.holder.update('')
			this.contentState = 'empty'
		}
	}
	, show: function(){
		this.loadContent()
		this.element.show()
		VDGallery.init()
		addthis.toolbox(this.element.down('.addthis_toolbox'))
		this.element.select('div.to_top').each(function(toTop){
			toTop.observeClick(function(e){ window.scrollTo(0, 0); e.cancel() })
		})
	}
	, hide: function(){
		this.element.hide()
		this.unloadContentInIe()
	}
	, fade: function(duration){
		if (this.element.visible()) {
			this.element.fade({duration:0.25, afterFinish:this.unloadContentInIe.bind(this)})
		}
	}
	, getHeight: function(){
		return this.element.getHeight() + this.element.getStyle('marginTop').toI() + this.element.getStyle('marginBottom').toI()
	}
})
Object.extend(VDFloatingPage, {
	init: function(){
		if (this.floatingPages = $('floating_pages')) {
			this.pages = $H()
			this.floatingPages.setStyle({visibility:'hidden'})
			this.floatingPages.show()
			this.floatingPages.select('li.page').each(function(page){
				var close = page.down('div.close')
				if (close) {
					close.observeClick(this.hide.bind(this))
				}
				this.pages.set(page.id, new VDFloatingPage(page))
				page.hide()
			}.bind(this))
			this.floatingPages.hide()
			this.floatingPages.setStyle({visibility:''})
		}
	}
	, setTop: function(top){
		this.floatingPages.setStyle({top:top + 'px'})
	}
	, page_exists: function(id){
		return !!this.pages.get(id)
	}
	, data: $H()
	, setData: function(id, data){
		this.data.set(id, data.replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&'))
	}
	, show: function(id){
		var page = this.pages.get(id)
		if (page) {
			Effect.ScrollTo($('html'), { duration:'0.5'})
			page.show()
			if (!this.floatingPages.visible()) {
				this.floatingPages.setOpacity(0)
				this.floatingPages.show()
				this.floatingPages.appear({duration:0.3})
			} else {
				this.pages.values().without(page).invoke('hide')
			}
			VDEvent.extendTop(page.getHeight())
			var viewportScroll = document.viewport.getScrollOffsets()
			new Effect.Tween(this, viewportScroll.top, 0, {duration: [0.001 * viewportScroll.top, 0.5].min()}, function(left, top){
			}.bind(this, viewportScroll.left))
			VDAnchorWatcher.wentTo('Pages', page.element)
			VDOrangeLine.stopMoveLineInterval()
			Slide.init()
			FestivalEvents.init()
		}
	}
	, hide: function(){
		VDEvent.shrinkTop()
		this.pages.values().invoke('fade')
		this.floatingPages.fade({duration:0.3})
		VDBar.unPress('popup')
		VDAnchorWatcher.wentToRoot()
		VDOrangeLine.startMoveLineInterval()
	}
})

var VDAnchorWatcher = {
	init: function(){
		SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.onChange.bind(this))
		SWFAddress.setStrict(false)
		this.onChange()
		this.initialized = true
	}
	, onChange: function(){
		var path = SWFAddress.getPathNames()
		switch(path[0]){
			case 'pages':
				VDBar.click('popup', path[1])
				break
			case 'events':
				VDEvent.open(SWFAddress.getValue())
				break
		}
	}
	, wentTo: function(group, element){
		if (this.initialized) {
			var path = element.readAttribute('rel')
			if (typeof(pageTracker) == 'object') {
				pageTracker._trackEvent('Pages', path)
			}
			SWFAddress.setValue(path)
		}
	}
	, wentToRoot: function(){
		if (this.initialized) {
			SWFAddress.setValue('/')
		}
	}
}

var VDFuckingAdCode = {
	insert: function(name){
		var rnd = Math.round(Math.random() * 1000000000);
		var referrer = document.referrer ? escape(document.referrer) : 'unknown'
		var html = '<img src="http://ad.adriver.ru/cgi-bin/rle.cgi?' + 'sid=137987&sz=' + name + '&bt=21&pz=0&rnd=' + rnd + '&tail256=' + referrer + '" border=0 width=1 height=1>'
		$('ad_shit').insert({bottom:html})
	}
}

var Slide = {
	init: function() {
		if (this.slideContainer = $('promos')) {
			this.slideContainer.select('.clickable').each(function(switchObj){
				switchObj.observe('click', this.slide)
				switchObj.observe('mousedown', function(e){e.stop()})
			}.bind(this))
		}
	},
	slide: function() {
		duration = 0.5

		this.clickedObject = this.up('li')
		slideContent = this.clickedObject.up('ul').next('.promoWrapper').down('li.' + this.clickedObject.className)
		slideWrapper = this.clickedObject.up('ul').next('.promoWrapper')
		listWrapper = this.clickedObject.up('ul')
		slideContentWrapper = this.clickedObject.up('ul').next('.promoWrapper').down('ul')
		slideContentMargins = 40
		newHeight = slideContent.getHeight() + slideContentMargins
		listWrapper.select('li').each(function(switchObj){
			switchObj.id = ''
		})
		this.clickedObject.id = 'active'


		if (slideContent.getStyle('display') == 'block') {
			oldWrapperHeight = slideWrapper.getHeight()
			new Effect.Opacity(slideContentWrapper, {to: 0, duration: duration, afterFinish: function(){
				new Effect.Morph(slideWrapper, {style: 'height: 0px', duration: duration, afterFinish: function(){
					Slide.changeBodyMargin(oldWrapperHeight, -1)
					slideContent.removeClassName('opened')
					new Effect.Opacity(slideContentWrapper, {to: 1, duration: duration, afterFinish: function(){
						slideContentWrapper.removeClassName('show')
						listWrapper.select('li').each(function(switchObj){
							switchObj.id = ''
						})
					}})
				}})
			}.bind(this)})
		} else if (slideContentWrapper.getStyle('opacity') > 0) {
			Slide.changeBodyMargin((newHeight - slideContentWrapper.getHeight()), 1)
			new Effect.Opacity(slideContentWrapper, {to: 0, duration: duration, afterFinish: function(){
				slideContentWrapper.select('li').each(function(switchObj){
					switchObj.removeClassName('opened')
				})
				this.slideEffect = new Effect.Morph(slideWrapper, {style: 'height: '+newHeight+'px', duration: duration, afterFinish: function(){
					slideContent.addClassName('opened')
					new Effect.Opacity(slideContentWrapper, {to: 1, duration: duration, afterFinish: function(){
						slideContentWrapper.addClassName('show')
					}})
				}.bind(this)})
			}})
		} else {
			Slide.changeBodyMargin(newHeight, 1)
			this.slideEffect = new Effect.Morph(slideWrapper, {style: 'height: '+newHeight+'px', duration: duration, afterFinish: function(){
				slideContent.addClassName('opened')
				new Effect.Opacity(slideContentWrapper, {to: 1, duration: duration, afterFinish: function(){
					slideContentWrapper.addClassName('show')
				}})
			}.bind(this)})
		}
	},
	changeBodyMargin: function(height, offset) {
		oldMargin = $('body').cumulativeOffset()[1]
		$('body').setStyle({marginTop: (oldMargin + (height * offset)) + 'px'})
		$('floating_pages').setStyle({top: '-' + (oldMargin + (height * offset)) + 'px'})
	}
}

var FestivalEvents = {
	init: function(){
		if (this.container = $('festival_events')) {
			this.container.select('td').each(function(td){
				if (!td.associatedContent) {
					if (td.associatedContent = $(td.id + '_content')) {
						td.observeClick(this.open.bind(this, td))
					}
				}
			}, this)
		}
	}
	, open: function(td) {
		if (this.opened) {
			this.opened.removeClassName('opened')
			this.opened.associatedContent.hide()
		}
		if (this.opened == td) {
			this.opened = null
		} else {
			this.opened = td
			td.addClassName('opened')
			td.associatedContent.show()
		}
	}
}

var CommentsForm = {
	init: function() {
		if (form = $('commentForm')) {
			var inputs = form.select("input[type=text], textarea")
			inputs.each(function(field){
				field.observe('change', this.checkForm)
				field.observe('keydown', this.checkForm)
			}.bind(this))
		}
	},
	checkForm: function() {
		var inputs = form.select("input[type=text], textarea")
		inputs.each(function(input){
			if (input.value == '' || (form.down('.comment_email_holder').down('input').value.match(/[\w+0-9._%+-]+@[\w+0-9.-]+\.[\w+]{2,4}$/) == null)) {
				$('comment_submit').addClassName('disabled')
				$('comment_submit').removeClassName('active')
				$('comment_submit').writeAttribute("disabled", "disabled")
			} else {
				$('comment_submit').removeClassName('disabled')
				$('comment_submit').addClassName('active')
				$('comment_submit').removeAttribute('disabled')
			}
		})
	}
}