// Copyright 2017-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.MaterialButtons

class FloatingButtonExampleSwiftViewController: UIViewController {

  let miniFloatingButton = MDCFloatingButton(frame: .zero, shape: .mini)
  let defaultFloatingButton = MDCFloatingButton()
  let largeIconFloatingButton = MDCFloatingButton()

  override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = UIColor(white: 0.9, alpha: 1)

    let plusImage = #imageLiteral(resourceName: "Plus")
    let plusImage36 = UIImage(named: "plus_white_36", in: Bundle(for: type(of: self)),
                              compatibleWith: traitCollection)

    miniFloatingButton.sizeToFit()
    miniFloatingButton.translatesAutoresizingMaskIntoConstraints = false
    miniFloatingButton.setMinimumSize(CGSize(width: 96, height: 40), for: .mini, in: .expanded)
    miniFloatingButton.setImage(plusImage, for: .normal)
    miniFloatingButton.accessibilityLabel = "Create"

    defaultFloatingButton.sizeToFit()
    defaultFloatingButton.translatesAutoresizingMaskIntoConstraints = false
    defaultFloatingButton.setImage(plusImage, for: .normal)
    defaultFloatingButton.accessibilityLabel = "Create"

    largeIconFloatingButton.sizeToFit()
    largeIconFloatingButton.translatesAutoresizingMaskIntoConstraints = false
    largeIconFloatingButton.setImage(plusImage36, for: .normal)
    largeIconFloatingButton.accessibilityLabel = "Create"
    largeIconFloatingButton.setContentEdgeInsets(UIEdgeInsetsMake(-6, -6, -6, 0), for: .default,
                                                 in: .expanded)

    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.text = "Try me on an iPad!"

    view.addSubview(label)
    view.addSubview(miniFloatingButton)
    view.addSubview(defaultFloatingButton)
    view.addSubview(largeIconFloatingButton)

    let totalHeight = miniFloatingButton.bounds.standardized.height +
                      defaultFloatingButton.bounds.standardized.height +
                      largeIconFloatingButton.bounds.standardized.height +
                      20 // 10 points between buttons

    let miniDefaultDifference = defaultFloatingButton.bounds.standardized.width -
                                miniFloatingButton.bounds.standardized.width

    leadingAlignView(view: miniFloatingButton, onView: self.view,
                     horizontalOffset: 10 + miniDefaultDifference / 2,
                     verticalOffset: -totalHeight / 2)
    leadingAlignView(view: defaultFloatingButton, onView: miniFloatingButton,
                     horizontalOffset: -miniDefaultDifference / 2,
                     verticalOffset: defaultFloatingButton.bounds.standardized.height + 10)
    leadingAlignView(view: largeIconFloatingButton, onView: defaultFloatingButton,
                     horizontalOffset: 0,
                     verticalOffset: defaultFloatingButton.bounds.standardized.height + 10)
    self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal,
                                               toItem: view, attribute: .centerX, multiplier: 1,
                                               constant: 0))
    self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .bottom, relatedBy: .equal,
                                               toItem: miniFloatingButton, attribute: .top,
                                               multiplier: 1, constant: -20))
  }

  // MARK: Private

  private func leadingAlignView(view: UIView, onView: UIView, horizontalOffset: CGFloat,
                                verticalOffset: CGFloat) {
    self.view.addConstraint(NSLayoutConstraint(
      item: view,
      attribute: .leading,
      relatedBy: .equal,
      toItem: onView,
      attribute: .leading,
      multiplier: 1.0,
      constant: horizontalOffset))

    self.view.addConstraint(NSLayoutConstraint(
      item: view,
      attribute: .centerY,
      relatedBy: .equal,
      toItem: onView,
      attribute: .centerY,
      multiplier: 1.0,
      constant: verticalOffset))
  }
}

extension FloatingButtonExampleSwiftViewController {

  class func catalogMetadata() -> [String: Any] {
    return [
      "breadcrumbs": ["Buttons", "Floating Action Button (Swift)"],
      "primaryDemo": false,
      "presentable": false,
    ]
  }
}

extension FloatingButtonExampleSwiftViewController {
  func updateFloatingButtons(to mode: MDCFloatingButtonMode) {
    if (miniFloatingButton.mode != mode) {
      miniFloatingButton.mode = mode
    }
    if (defaultFloatingButton.mode != mode) {
      defaultFloatingButton.mode = mode
    }
    if (largeIconFloatingButton.mode != mode) {
      largeIconFloatingButton.mode = mode
    }
  }

  func updateFloatingButtons(whenSizeClass isRegularRegular: Bool) {
    if (isRegularRegular) {
      updateFloatingButtons(to: .expanded)
      miniFloatingButton.setTitle("Add", for: .normal)
      defaultFloatingButton.setTitle("Create", for: .normal)
      largeIconFloatingButton.setTitle("Create", for: .normal)
    } else {
      updateFloatingButtons(to: .normal)
      miniFloatingButton.setTitle(nil, for: .normal)
      defaultFloatingButton.setTitle(nil, for: .normal)
      largeIconFloatingButton.setTitle(nil, for: .normal)
    }
  }

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let horizontalSizeClass = traitCollection.horizontalSizeClass
    let verticalSizeClass = traitCollection.verticalSizeClass
    let isRegularRegular = horizontalSizeClass == .regular && verticalSizeClass == .regular
    updateFloatingButtons(whenSizeClass: isRegularRegular)
  }

  override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
    super.willTransition(to: newCollection, with: coordinator)
    let currentTraits = traitCollection
    let sizeClassChanged =
      newCollection.horizontalSizeClass != currentTraits.horizontalSizeClass ||
        newCollection.verticalSizeClass != currentTraits.verticalSizeClass
    if (sizeClassChanged) {
      let willBeRegularRegular =
        newCollection.horizontalSizeClass == .regular &&
          newCollection.verticalSizeClass == .regular

      coordinator.animate(alongsideTransition:{ (_) in
        self.updateFloatingButtons(whenSizeClass: willBeRegularRegular)
      }, completion: nil)
    }
  }
}
