/*
 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

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)

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

    largeIconFloatingButton.sizeToFit()
    largeIconFloatingButton.translatesAutoresizingMaskIntoConstraints = false
    largeIconFloatingButton.setImage(plusImage36, for: .normal)
    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 {
  @objc class func catalogBreadcrumbs() -> [String] {
    return ["Buttons", "Floating Action Button (Swift)"]
  }

  @objc class func catalogIsPrimaryDemo() -> Bool {
    return 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)
    }
  }
}
