// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "modules/media_controls/elements/MediaControlLoadingPanelElement.h"

#include "core/css/CSSStyleDeclaration.h"
#include "core/dom/ElementShadow.h"
#include "core/dom/events/Event.h"
#include "core/dom/events/EventListener.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLStyleElement.h"
#include "core/html/media/HTMLMediaElement.h"
#include "core/style/ComputedStyle.h"
#include "modules/media_controls/MediaControlsImpl.h"
#include "modules/media_controls/MediaControlsResourceLoader.h"
#include "modules/media_controls/elements/MediaControlElementsHelper.h"

namespace {

static const char kAnimationIterationCountName[] = "animation-iteration-count";
static const char kInfinite[] = "infinite";

}  // namespace

namespace blink {

MediaControlLoadingPanelElement::MediaControlLoadingPanelElement(
    MediaControlsImpl& media_controls)
    : MediaControlDivElement(media_controls, kMediaControlsPanel) {
  SetShadowPseudoId(AtomicString("-internal-media-controls-loading-panel"));
  CreateShadowRootInternal();

  // The loading panel should always start hidden.
  SetIsWanted(false);
}

// The shadow DOM structure looks like:
//
// #root
// +- #spinner-frame
//   +- #spinner
//     +- #layer
//     | +- #spinner-mask-1
//     | | +- #spinner-mask-1-background
//     \ +- #spinner-mask-2
//         +- #spinner-mask-2-background
// +- #cutoff-1
// +- #cutoff-2
// +- #cutoff-3
// +- #cutoff-4
// +- #fake-timeline
void MediaControlLoadingPanelElement::PopulateShadowDOM() {
  ShadowRoot* shadow_root = YoungestShadowRoot();
  DCHECK(!shadow_root->HasChildren());

  // This stylesheet element and will contain rules that are specific to the
  // loading panel. The shadow DOM protects these rules and rules from the
  // parent DOM from bleeding across the shadow DOM boundary.
  HTMLStyleElement* style = HTMLStyleElement::Create(GetDocument(), false);
  style->setTextContent(
      MediaControlsResourceLoader::GetShadowLoadingStyleSheet());
  shadow_root->AppendChild(style);

  // The spinner frame is centers the spinner in the middle of the element and
  // cuts off any overflowing content. It also contains a SVG mask which will
  // overlay the spinner and cover up any rough edges created by the moving
  // elements.
  HTMLDivElement* spinner_frame =
      MediaControlElementsHelper::CreateDivWithId("spinner-frame", shadow_root);

  // The spinner is responsible for rotating the elements below. The square
  // edges will be cut off by the frame above.
  HTMLDivElement* spinner =
      MediaControlElementsHelper::CreateDivWithId("spinner", spinner_frame);

  // The layer performs a secondary "fill-unfill-rotate" animation.
  HTMLDivElement* layer =
      MediaControlElementsHelper::CreateDivWithId("layer", spinner);

  // The spinner is split into two halves, one on the left (1) and the other
  // on the right (2). The mask elements stop the background from overlapping
  // each other. The background elements rotate a SVG mask from the bottom to
  // the top. The mask contains a white background with a transparent cutout
  // that forms the look of the transparent spinner. The background should
  // always be bigger than the mask in order to ensure there are no gaps
  // created by the animation.
  HTMLDivElement* mask1 =
      MediaControlElementsHelper::CreateDivWithId("spinner-mask-1", layer);
  mask1_background_ = MediaControlElementsHelper::CreateDivWithId(
      "spinner-mask-1-background", mask1);
  HTMLDivElement* mask2 =
      MediaControlElementsHelper::CreateDivWithId("spinner-mask-2", layer);
  mask2_background_ = MediaControlElementsHelper::CreateDivWithId(
      "spinner-mask-2-background", mask2);

  event_listener_ = new MediaControlAnimationEventListener(this);

  // The four cutoffs are responsible for filling the background of the loading
  // panel with white, whilst leaving a small box in the middle that is
  // transparent. This is where the spinner will be.
  MediaControlElementsHelper::CreateDivWithId("cutoff-1", shadow_root);
  MediaControlElementsHelper::CreateDivWithId("cutoff-2", shadow_root);
  MediaControlElementsHelper::CreateDivWithId("cutoff-3", shadow_root);
  MediaControlElementsHelper::CreateDivWithId("cutoff-4", shadow_root);

  // The fake timeline creates a fake bar at the bottom to look like the
  // timeline.
  MediaControlElementsHelper::CreateDivWithId("fake-timeline", shadow_root);
}

void MediaControlLoadingPanelElement::RemovedFrom(
    ContainerNode* insertion_point) {
  if (event_listener_) {
    event_listener_->Detach();
    event_listener_.Clear();
  }

  MediaControlDivElement::RemovedFrom(insertion_point);
}

void MediaControlLoadingPanelElement::CleanupShadowDOM() {
  // Clear the shadow DOM children and all references to it.
  ShadowRoot* shadow_root = YoungestShadowRoot();
  DCHECK(shadow_root->HasChildren());
  event_listener_->Detach();
  shadow_root->RemoveChildren();

  mask1_background_.Clear();
  mask2_background_.Clear();
  event_listener_.Clear();
}

void MediaControlLoadingPanelElement::SetAnimationIterationCount(
    const String& count_value) {
  mask1_background_->style()->setProperty(&GetDocument(),
                                          kAnimationIterationCountName,
                                          count_value, "", ASSERT_NO_EXCEPTION);
  mask2_background_->style()->setProperty(&GetDocument(),
                                          kAnimationIterationCountName,
                                          count_value, "", ASSERT_NO_EXCEPTION);
}

void MediaControlLoadingPanelElement::UpdateDisplayState() {
  switch (state_) {
    case State::kHidden:
      // If the media controls are loading metadata then we should show the
      // loading panel and insert it into the DOM.
      if (GetMediaControls().State() == MediaControlsImpl::kLoadingMetadata) {
        PopulateShadowDOM();
        SetIsWanted(true);
        SetAnimationIterationCount(kInfinite);
        state_ = State::kPlaying;
      }
      break;
    case State::kPlaying:
      // If the media controls are either stopped or playing then we should
      // hide the loading panel, but not until the current cycle of animations
      // is complete.
      if (GetMediaControls().State() != MediaControlsImpl::kLoadingMetadata) {
        SetAnimationIterationCount(WTF::String::Number(animation_count_ + 1));
        state_ = State::kCoolingDown;
      }
      break;
    case State::kCoolingDown:
      // Do nothing.
      break;
  }
}

void MediaControlLoadingPanelElement::OnAnimationEnd() {
  // If we have gone back to the loading metadata state (e.g. the source
  // changed). Then we should jump back to playing.
  if (GetMediaControls().State() == MediaControlsImpl::kLoadingMetadata) {
    state_ = State::kPlaying;
    SetAnimationIterationCount(kInfinite);
    return;
  }

  // The animation has finished so we can go back to the hidden state and
  // cleanup the shadow DOM.
  SetIsWanted(false);
  state_ = State::kHidden;
  animation_count_ = 0;
  CleanupShadowDOM();
}

void MediaControlLoadingPanelElement::OnAnimationIteration() {
  animation_count_ += 1;
}

Element& MediaControlLoadingPanelElement::WatchedAnimationElement() const {
  DCHECK(mask1_background_);
  return *mask1_background_;
}

void MediaControlLoadingPanelElement::Trace(blink::Visitor* visitor) {
  MediaControlAnimationEventListener::Observer::Trace(visitor);
  MediaControlDivElement::Trace(visitor);
  visitor->Trace(event_listener_);
  visitor->Trace(mask1_background_);
  visitor->Trace(mask2_background_);
}

}  // namespace blink
