Control 	= require './index'
Container 	= window.require 'spine/controller/container'

limit = (value, min, max) -> Math.max Math.min(max, Number value), min
$body = $ 'body'

class Slider extends Control
	@include Container
	template  : 'core/views/slider'

	className : 'control-slider'

	elements :
		'.input-slider-thumb':      'thumb'
		'.input-slider':            'input'
		'.input-slider-value':      'text'
		'.input-slider-container':  'container'

	events:
		'mousedown .input-slider-thumb':  'startDrag'
		'mousedown .input-slider':        'trackClick'
		'focus input':                    'focus'
		'keydown input':                  'keydown'
	
	pageX: 0
	isMouseDown: false

	constructor: ->
		super
		@options.min  or= 0
		@options.max  or= 1
		@options.unit or= ''

		@text.bind 'blur', @blur

	mouseEnterBody: (e) =>
		return unless @isMouseDown
		@stopDrag e if (e.buttons || e.which) isnt 1

	update: (item,type,options={}) =>
		return if options.from and options.from is @

		val = if item[@attribute]? then item[@attribute] else @options.default
		@thumb.css left: @_valToPos val
		@value parseInt limit val, @options.min, @options.max

	startDrag: (e) =>
		@isMouseDown = true
		e.stopPropagation()
		e.preventDefault()

		@input.focus()
		#Cache 
		@tw = @thumb.width()
		
		($body = $ @el[0].ownerDocument.body).bind('mousemove', @drag)
			.bind('mouseup', @stopDrag)
			.addClass('thumb-dragging')
			.unbind('mouseenter', @mouseEnterBody)
			.bind 'mouseenter', @mouseEnterBody

		clearInterval @interval
		@interval = setInterval @liveUpdate, 100

	stopDrag: (e) =>
		$body.unbind('mousemove', @drag)
			.unbind('mouseup',@stopDrag)
			.removeClass 'thumb-dragging'

		clearInterval(@interval)
		@liveUpdate()
		@isMouseDown = false

	drag: (e) =>
		e.preventDefault()
		@pageX = e.pageX
		@thumb.css left: @mouseToLocal()

	mouseToLocal: =>
		limit @pageX - @container.offset().left - @tw/2, 0, @container.width()-@tw

	liveUpdate: =>
		val = @_posToVal()
		@value parseInt val
		@item.updateAttribute @attribute,val, {@attribute, from:@}
		@

	trackClick: (e) =>
		e.preventDefault()
		@tw = @thumb.width()
		@pageX = e.pageX
		@thumb.animate left: @mouseToLocal(), 300, @liveUpdate

	_posToVal: =>
		(@options.max-@options.min)*(@thumb.position().left)/(@container.width()-@tw) + Number(@options.min)

	_valToPos:(val)=>
		cw = @container.width()-@thumb.width()
		pos = (((val-@options.min)*100/(@options.max-@options.min))/100)
		pos = if cw then limit cw*pos, 0, cw else limit(pos*100, 0, 100)+'%'
	
	focus: ->
		@text.val @lastValue

	value: (val) ->
		return @text.val (@lastValue = val)+@options.unit if val?
		if isNaN v=parseInt @text.val() then +@lastValue else v

	blur: =>
		val = limit @value(), @options.min, @options.max
		@thumb.css left: @_valToPos(val)
		@value parseInt val
		@item.updateAttribute @attribute, val, {@attribute, from: @}

	keydown: (e) ->
		@blur() if e.keyCode is 13

	release: ->
		clearInterval @interval
		super

module.exports = Slider