     animation
 
   ###*
+    @protected
     @return {number} actual computed height of element
   ###
   getHeight: ->

  ###
  decorate: (@dropupButton) ->
    # arrow span, allowing change of icon according to state
    @caretElement = @dropupButton.querySelector ".#{wzk.ui.dropup.Dropup.CSS.CARET}"

    # id of tag to dropup
    dropupSelector = goog.dom.dataset.get @dropupButton, wzk.ui.dropup.Dropup.CSS.TARGET_ATTRIBUTE
    unless dropupSelector?
      throw new Error "Dropup button element has no '#{wzk.ui.dropup.Dropup.CSS.TARGET_ATTRIBUTE}' attribute!"

    # find element with id or class
    @dropupElement = @dom.one "##{dropupSelector}, .#{dropupSelector}", @dom.getDocument()
    unless @dropupElement?
      console.warn "Dropup element with specified id or class  '#{dropupSelector}', does not exist!"
      return

    # hide dropupElement right after registering
    goog.style.setElementShown @dropupElement, false

    # set overflow property
    @dropupElement.style.overflow = 'hidden'

    # when animation is running, lock is set to true
    @animationLock = false

    # register handler for button
    goog.events.listen @dropupButton, goog.events.EventType.CLICK, @toggle

  ###*
    @protected

  ###
  open: ->
    @height ?= @getHeight()
    goog.style.setElementShown(@dropupElement, true)
    animation = @getAnimation(0, @height)
    CLS = wzk.ui.dropup.Dropup.CLS

    animation.listen goog.fx.Animation.EventType.BEGIN, (event) =>
      for el in @getAllElements()
        goog.dom.classes.addRemove(el, CLS.CLOSED, CLS.OPENED)

    animation.listen goog.fx.Animation.EventType.FINISH, (event) =>
      goog.dom.classes.remove(@dropupElement, CLS.COLLAPSE)
      @swapClasses()

    animation.play()
