Control = require './index'
Spinner = require './stepper'

###
	Initialize with {item:{skin instance},attribute:'attribute',options:{options from meta}}
###
class Color extends Control
	template	: 'core/views/color'
	className	: 'control-color'
	events		:
		'input .control-input':'_change'
		'click .color-preview-i': 'toggle'
	elements 	:
		'.control-input':   'input'
		'.color-preview':   'color'
		'.color-preview-i': 'colorPreview'

	render:=>
		super

		@_updatePreviewColor()

		@listenTo $(document), 'click', => if @popup?.visible then @deactivate()
		@

	toggle: =>
		@_createPopup().then => if @popup.visible then @popup.hide() else @popup.show()

	update: (item, type, options = {}) =>
		value = if item[@attribute]? then item[@attribute] else @options.default

		if options.from isnt @
			@input.val @tinycolor(value).toString('hex6')

		if options.from isnt @color
			@spectrum @color, 'set', value

		color = @tinycolor(value).toRgb()
		@spinner?.change color.a*100, silent:true
		@_updatePreviewColor item

	_createPopup: ->
		return @popupPromise if @popupPromise
		@popupPromise = Blogvio.UI.popup.new
				anchor: @colorPreview
				targetWindow: @targetWindow
				css: @css or [
					'https://widgetic.com/bundles/blogvioapp/css/editor/editor.css'
				]
			.then (@popup) =>
				@spectrum(@color,
					document: @popup.document
					preview: @colorPreview.find(".sp-preview-inner")
					flat: true,
					showAlpha:true,
					showInitial:true,
					showInput:true,
					preferredFormat:'hex6',
					showButtons:false,
					clickoutFiresChange: true,
					change:@colorChange,
					move:@colorChange,
					color:@item[@attribute]
					input:(color)=>
						oc = color.toRgb()
						oc.a = @spinner.input.val()/100
						@spectrum @color, 'setTemp', oc
						@colorChange(@tinycolor(oc));
				)

				cont = @spectrum @color, 'container'
				alpha =  (not (alp = @options.alpha)?) or String(alp) is true
				cont.toggleClass 'sp-alpha-enabled', alpha

				@spinner = new Spinner
					className: 'control control-stepper sp-alpha-step'
					body: $ @popup.body
					attribute:'opacity',
					options  :
						min 	: 0
						max		: 100
						default	: @tinycolor(@item[@attribute]).toRgb().a*100
				@spinner.bind 'change:stepper',@_updateOpacity

				cont.find('.sp-input-container').append @spinner.render().el
				cont.find('.sp-input-container .sp-input').attr 'maxLength','7'
				# cont.css('display', 'inline-block')
				@popup.append(cont)
				# cont.css('display', 'none')
				$(@popup.document.body).bind 'mouseenter', @mouseEnterBody
			.fail (err) ->
				console.error err.stack

	_updatePreviewColor: (item) ->
		@colorPreview.find(".sp-preview-inner").css
			backgroundColor: (item or @item)[@attribute]

	_updateOpacity: (o = {}) =>
		return unless @popup.visible
		oc = @spectrum(@color, 'get').toRgb()
		oc.a = o.val/100
		@spectrum @color, 'setTemp', oc
		@colorChange @tinycolor(oc)

	_change: =>
		@colorChange @tinycolor(@input.val()), from: @

	colorChange: (color, options = {}) =>
		@change color.toRgbString(), $.extend {@attribute, from: @color}, options

	deactivate: =>
		@popup?.hide()

	release: ->
		# destroy spectrum before removing @el from the DOM
		# as it depends on some data saved on the DOM element
		# which is lost after removal
		@spectrum @color, 'destroy'
		@popup?.release()
		super

	mouseEnterBody: (e) =>
		if (e.buttons || e.which) isnt 1
			$(e.target.ownerDocument.body).trigger 'mouseup'

	tinycolor: ->
		window.tinycolor arguments...

	spectrum: (input, data...) ->
		$(input).spectrum data...

	setPopupTargetWindow: (@targetWindow) => @

module.exports = Color
