// Copyright 2020-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import UIKit
import MaterialComponents.MaterialAppBar
import MaterialComponents.MaterialAppBar_Theming 
import MaterialComponents.MaterialBottomNavigation
import MaterialComponents.MaterialButtons
import MaterialComponents.MaterialButtons_Theming 
import MaterialComponents.MaterialCards
import MaterialComponents.MaterialCards_Theming 
import MaterialComponents.MaterialShadowElevations
import MaterialComponents.MaterialContainerScheme

/// An example for testing the performance of `MDCShadowLayer`. This example is not intended to
/// demonstrate how to setup any specific components but rather to push `MDCShadowLayer` to the
/// limits for metric testing.
class MDCShadowPerformanceExample:
  UIViewController,
  UICollectionViewDelegate,
  UICollectionViewDataSource,
  UICollectionViewDelegateFlowLayout
{

  /// Injected `MDCAppBarViewController` so we can render the shadow on it.
  lazy var appBar = makeAppBar()

  /// The _plus_ FAB.
  let createButton = MDCFloatingButton()

  /// Used to render a _top_ shadow on a component that is pinned to the bottom.
  let bottomNavBar = MDCBottomNavigationBar()

  /// Used for styling the sub components based on the app container scheme.
  // `@objc` is required for `setupTransition` to work within `MDCDragonsController`.
  @objc var containerScheme: MDCContainerScheming = MDCContainerScheme()

  /// The main scroll view content.
  let collectionView = UICollectionView(
    frame: .zero,
    collectionViewLayout: UICollectionViewFlowLayout())

  /// Number of cells in the `collectionView`.
  let cellCount = 200

  /// Cell reuse identifier.
  let cellIdentifier = "Cell"

  /// Padding between cells.
  let defaultPadding: CGFloat = 8

  /// The title of the example
  fileprivate static let exampleTitle = "Shadow & Performance"

  override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = containerScheme.colorScheme.backgroundColor
    appBar.headerView.observesTrackingScrollViewScrollEvents = true
    appBar.applyPrimaryTheme(withScheme: containerScheme)
    appBar.didMove(toParent: self)
    appBar.navigationBar.title = MDCShadowPerformanceExample.exampleTitle

    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.backgroundColor = containerScheme.colorScheme.backgroundColor
    collectionView.alwaysBounceVertical = true
    collectionView.register(MDCCardCollectionCell.self, forCellWithReuseIdentifier: cellIdentifier)
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(collectionView)
    view.addSubview(appBar.view)
    appBar.headerView.trackingScrollView = collectionView

    createButton.sizeToFit()
    let plusImage = UIImage(named: "system_icons/add")
    createButton.setImage(plusImage, for: .normal)
    createButton.accessibilityLabel = "Create"
    createButton.applySecondaryTheme(withScheme: containerScheme)
    view.addSubview(createButton)

    view.addSubview(bottomNavBar)
    bottomNavBar.titleVisibility = .always
    bottomNavBar.alignment = .centered
    let tabBarItem1 = UITabBarItem(
      title: "Home", image: UIImage(named: "system_icons/home"), tag: 0)
    let tabBarItem2 =
      UITabBarItem(title: "Messages", image: UIImage(named: "system_icons/email"), tag: 1)
    bottomNavBar.items = [tabBarItem1, tabBarItem2]
    bottomNavBar.selectedItem = tabBarItem2
  }

  override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    let width = view.bounds.width
    let height = view.bounds.height
    var safeArea: UIEdgeInsets = .zero
    safeArea = view.safeAreaInsets
    collectionView.contentInsetAdjustmentBehavior = .always

    collectionView.frame = CGRect(
      origin: .zero, size: CGSize(width: width, height: height - (safeArea.bottom + safeArea.top)))

    let size = bottomNavBar.sizeThatFits(view.bounds.size)
    var bottomNavBarFrame = CGRect(
      x: 0,
      y: height - size.height,
      width: size.width,
      height: size.height)
    bottomNavBarFrame.size.height += safeArea.bottom
    bottomNavBarFrame.origin.y -= safeArea.bottom
    bottomNavBar.frame = bottomNavBarFrame

    let createButtonDimension: CGFloat = 56
    let createButtonPadding: CGFloat = 16
    createButton.frame = CGRect(
      x: width - (createButtonDimension + safeArea.left + createButtonPadding),
      y: bottomNavBarFrame.origin.y - (createButtonDimension + createButtonPadding),
      width: createButtonDimension,
      height: createButtonDimension
    )
  }

  private func makeAppBar() -> MDCAppBarViewController {
    let appBarViewController = MDCAppBarViewController()
    addChild(appBarViewController)
    appBarViewController.headerView.minMaxHeightIncludesSafeArea = false
    appBarViewController.inferTopSafeAreaInsetFromViewController = true
    appBarViewController.headerView.canOverExtend = false
    return appBarViewController
  }

  // MARK: Collection View methods

  func collectionView(
    _ collectionView: UICollectionView,
    cellForItemAt indexPath: IndexPath
  ) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(
      withReuseIdentifier: cellIdentifier, for: indexPath)
    guard let cardCell = cell as? MDCCardCollectionCell else { return cell }

    cardCell.enableRippleBehavior = true
    cardCell.isAccessibilityElement = true
    cardCell.accessibilityLabel = title
    cardCell.setShadowElevation(.cardResting, for: .normal)
    cardCell.applyTheme(withScheme: containerScheme)

    return cardCell
  }

  func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
  }

  func collectionView(
    _ collectionView: UICollectionView,
    numberOfItemsInSection section: Int
  ) -> Int {
    return cellCount
  }

  func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAt indexPath: IndexPath
  ) -> CGSize {
    let cardSize = (collectionView.bounds.size.width / 3) - 12
    return CGSize(width: cardSize, height: cardSize)
  }

  func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    insetForSectionAt section: Int
  ) -> UIEdgeInsets {
    return UIEdgeInsets(
      top: defaultPadding,
      left: defaultPadding,
      bottom: defaultPadding,
      right: defaultPadding
    )
  }

  func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    minimumLineSpacingForSectionAt section: Int
  ) -> CGFloat {
    return defaultPadding
  }

  func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    minimumInteritemSpacingForSectionAt section: Int
  ) -> CGFloat {
    return defaultPadding
  }
}

// MARK: Catalog by convention
extension MDCShadowPerformanceExample {
  @objc class func catalogMetadata() -> [String: Any] {
    return [
      "breadcrumbs": ["Shadow", MDCShadowPerformanceExample.exampleTitle],
      "primaryDemo": false,
      "presentable": true,
      "description": """
        This example is not intended to demonstrate how to setup any specific components but rather to
        push `MDCShadowLayer` to the limits for metric testing.
        """,
    ]
  }

  @objc func catalogShouldHideNavigation() -> Bool {
    return true
  }
}
