###
This component is intended to be used inside of a modal or popover, 
but could be used other places to confirm a save event was successful 

Confirm Save Props

@props.saveState - string 
  This can be either 'pending' or 'complete' or 'failed'
    - When 'pending', a spinner shows
    - When 'complete', a green check mark flashes before calling the done callback
    - When 'failed', a red x flashes before calling the fail callback

@props.done - method
  This method will be called animationDuration ms after the saveState hits complete
  It will usually be a method that closes the popover or modal

@props.fail - method
  This method will be called animationDuration ms after the saveState hits failed
  It will usually be a method that sets the parent's saveState back to null, which will remove this widget from the DOM

@props.scaleCheckmark - default 1
  percent to scale the confirm check and spinner

@props.vTranslateCheckmark - default 0
  number of pixels to move the checkmark up above the middle of the container

@props.animationDuration - default 800
  ms over which the check scalling takes place

Tips for using this..
- It is absolutely positioned w/ all zeroes, to add to the top level of the render tree
- Create a local 'saveState' state on your component, and default it to null
- render like this:

  ConfirmSave {
    key: 'confirm'
    done: @close
    saveState: @state.saveState
  } if @state.saveState?

  This way, when you trigger the save, also call @setState({saveState: 'pending'})
  Then pass a call back to the save action, which just calls @setState({saveState: 'complete'})

###

React = require 'react'
Animation = require 'ainojs-animation'
easing = require 'ainojs-easing'
Spinner = React.createFactory(require './spinner')

{div} = React.DOM

ConfirmSave = React.createClass
  
  displayName: 'ConfirmSave'

  getDefaultProps: ->
    scaleCheckmark: 1
    animationDuration: 800
    vTranslateCheckmark: 0
  
  getInitialState: ->
    scale: .25

  render: ->
    {saveState, scaleCheckmark, vTranslateCheckmark} = @props
    {scale} = @state

    content = (
      if saveState is 'pending'
        Spinner {
          lines: 12
          length: 10
          width: 3
          radius: 8
          color: 'white'
        } 
      else 
        checkClassName = 'confirm-check'
        checkClassName += ' failed' if saveState is 'failed'
        div {
          className: checkClassName
          style:
            transform: "scale(#{scale})"
            msTransform: "scale(#{scale})"
            WebkitTransform: "scale(#{scale})"
        }
    )

    div {
      className: 'confirm-save-wrap'
    }, div {
        className: 'confirm-frame'
        style:
          transform: "scale(#{scaleCheckmark}) translateY(#{vTranslateCheckmark}px)"
          msTransform: "scale(#{scaleCheckmark}) translateY(#{vTranslateCheckmark}px)"
          WebkitTransform: "scale(#{scaleCheckmark}) translateY(#{vTranslateCheckmark}px)"
      }, content

  componentWillMount: ->
    # Handles the case when the saveState is never pending
    if @props.saveState is 'complete' or @props.saveState is 'failed'
      @animateImmediately = yes

  componentDidMount: ->
    @animateCheck() if @animateImmediately

  componentDidUpdate: (prevProps) ->
    return unless prevProps.saveState is 'pending' and (@props.saveState is 'complete' or @props.saveState is 'failed')
    
    @animateCheck()

  animateCheck: ->
    if @animation?.isAnimating() then @animation.end()
    
    {scale} = @state 
    {animationDuration} = @props

    @animation = new Animation 
      duration: animationDuration
      easing: easing('easeOutElastic')
    .init {scale}
    .on 'frame', @onFrame
    .on 'complete', @end
    .animateTo {scale: 1}

  onFrame: (e) ->
    if @isMounted() then @setState e.values

  end: ->
    {saveState, done, fail} = @props
    if saveState is 'complete' then @props.done?()
    else @props.fail?()

module.exports = ConfirmSave