###
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 'warning', a yellow exclamation mark flashes before calling the done callback
    - When 'failed', a red x flashes before calling the fail callback

@props.saveMessage - string
  A message that will be displayed alongside the saveState imagery

@props.dismissBtnText - string
  Text that will be displayed as the dismiss button

@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, span, button} = React.DOM

ConfirmSave = React.createClass
  
  displayName: 'ConfirmSave'

  getDefaultProps: ->
    dismissBtnText: 'Dismiss'
    scaleCheckmark: 1
    animationDuration: 800
    vTranslateCheckmark: 0
    saveMessage: ''
  
  getInitialState: ->
    scale: .25

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

    if saveState is 'pending'
      content = Spinner {
        lines: 12
        length: 10
        width: 3
        radius: 8
        color: 'white'
      } 
    # Use a separate component for messages
    else if saveMessage
      checkClassName = 'confirm-check-message'
      checkClassName += ' failed' if saveState is 'failed'
      checkClassName += ' warning' if saveState is 'warning'

      # Don't do a scale animation when there's a message
      scaleCheckmark = 1

      content = [
        div {
          key: 'icon'
          className: checkClassName
        }, 
          span {
            className: 'confirm-message'
          }, saveMessage
        div {
          key: 'dismiss'
          className: 'message-dismiss'
        },
          button {
            onClick: @end
          }, dismissBtnText
      ]
    else 
      checkClassName = 'confirm-check'
      checkClassName += ' failed' if saveState is 'failed'
      checkClassName += ' warning' if saveState is 'warning'

      content = div {
        className: checkClassName
        style:
          transform: "scale(#{scale})"
          msTransform: "scale(#{scale})"
          WebkitTransform: "scale(#{scale})"
      }

    div {
      className: 'confirm-save-wrap' + if saveMessage then ' has-message' else ''
    }, 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 'warning' or @props.saveState is 'failed')
    @animateCheck()

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

    @animation = new Animation 
      duration: animationDuration
      easing: easing('easeOutElastic')
    .init {scale}
    .on 'frame', @onFrame
    .on 'complete', if saveMessage then -> else @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