//
//  MainViewController.swift
//  KeymanEngineDemo
//
//  Created by Gabriel Wong on 2017-10-05.
//  Copyright © 2017 SIL International. All rights reserved.
//

import KeymanEngine
import UIKit
import QuartzCore

class MainViewController: UIViewController, UIAlertViewDelegate, TextViewDelegate, TextFieldDelegate {
  var textView1: TextView!
  var textView2: TextField!
  var textView3: UITextView!

  private var keyboardPickerDismissedObserver: NotificationObserver?

  deinit {
    NotificationCenter.default.removeObserver(self)
  }

  override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    title = "Keyman Demo"

    NotificationCenter.default.addObserver(self, selector: #selector(self.resizeView),
                                           name: .UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.resizeView),
                                           name: .UIKeyboardWillHide, object: nil)
    keyboardPickerDismissedObserver = NotificationCenter.default.addObserver(
      forName: Notifications.keyboardPickerDismissed,
      observer: self,
      function: MainViewController.keyboardPickerDismissed)
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  // MARK: - View lifecycle
  override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = UIColor.gray
    navigationItem.rightBarButtonItem = KeyboardPickerBarButtonItem(presentingVC: self)

    let contentView = self.contentView()
    contentView.frame = view.bounds
    view.addSubview(contentView)
  }

  // TODO prevent autorotation to portraitUpsideDown

  // MARK: - Helper Methods
  func contentView() -> UIScrollView {
    let contentWidth: CGFloat = 320.0 // arbitrary non-zero width for now (it will get auto-resized)
    let margin: CGFloat = 10.0
    let contentView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: contentWidth, height: 1.0))

    // Labels
    let keymanLabel = UILabel()
    keymanLabel.text = "Keyman Text Views/Fields:"
    keymanLabel.numberOfLines = 0
    keymanLabel.lineBreakMode = .byWordWrapping
    keymanLabel.frame = CGRect(x: margin, y: margin, width: contentWidth - margin * 2.0, height: 40.0)
    keymanLabel.autoresizingMask = .flexibleWidth
    keymanLabel.backgroundColor = UIColor.clear
    keymanLabel.textColor = UIColor.white
    contentView.addSubview(keymanLabel)

    let normalLabel = UILabel()
    normalLabel.text = "Normal Text View:"
    normalLabel.numberOfLines = 0
    normalLabel.lineBreakMode = .byWordWrapping
    normalLabel.frame = CGRect(x: margin, y: margin, width: contentWidth - margin * 2.0, height: 40.0)
    normalLabel.autoresizingMask = .flexibleWidth
    normalLabel.backgroundColor = UIColor.clear
    normalLabel.textColor = UIColor.white
    contentView.addSubview(normalLabel)

    // Text Views/Fields
    textView1 = TextView()
    textView2 = TextField()
    textView3 = UITextView()
    setTextViewStyle(textView1)
    setTextFieldStyle(textView2)
    setTextViewStyle(textView3)

    textView1.setKeymanDelegate(self)
    textView2.setKeymanDelegate(self)
    textView2.placeholder = "text field"
    textView2.borderStyle = .roundedRect
    textView2.clearButtonMode = .whileEditing

    textView1.frame = CGRect(x: margin, y: keymanLabel.frame.maxY + 5.0,
                             width: contentView.frame.width - margin * 2.0, height: 80.0)
    textView2.frame = CGRect(x: margin, y: textView1.frame.maxY + margin,
                             width: contentView.frame.width - margin * 2.0, height: 30.0)
    normalLabel.frame = CGRect(x: margin, y: textView2.frame.maxY + margin,
                               width: contentWidth - margin * 2.0, height: 40.0)
    textView3.frame = CGRect(x: margin, y: normalLabel.frame.maxY + margin,
                             width: contentWidth - margin * 2.0, height: 40.0)

    textView1.viewController = self
    textView2.viewController = self
    contentView.addSubview(textView1)
    contentView.addSubview(textView2)
    contentView.addSubview(textView3)

    // Button - keyboard picker
    let kbButton = KeyboardPickerButton(presentingVC: self)
    kbButton.center = CGPoint(x: contentWidth / 2.0, y: textView3.frame.maxY + 30.0)
    kbButton.frame = kbButton.frame.integral
    kbButton.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin]
    contentView.addSubview(kbButton)

    // Button - close keyboard
    let dismissButton = UIButton(type: .roundedRect)
    dismissButton.setTitle("Close Keyboard", for: .normal)
    dismissButton.addTarget(self, action: #selector(self.dismissKeyboard), for: .touchUpInside)
    dismissButton.sizeToFit()
    dismissButton.center = CGPoint(x: contentWidth / 2.0, y: kbButton.frame.maxY + 30.0)
    dismissButton.frame = dismissButton.frame.integral
    dismissButton.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin]
    contentView.addSubview(dismissButton)

    // Button - download custom keyboard
    let downloadButton = UIButton(type: .roundedRect)
    downloadButton.setTitle("Download custom keyboard", for: .normal)
    downloadButton.sizeToFit()
    downloadButton.center = CGPoint(x: contentWidth / 2.0, y: dismissButton.frame.maxY + 30.0)
    downloadButton.frame = downloadButton.frame.integral
    downloadButton.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin]
    contentView.addSubview(downloadButton)

    // Content view setup
    contentView.frame = CGRect(x: 0.0, y: 0.0, width: contentWidth, height: downloadButton.frame.maxY + margin)
    contentView.contentSize = contentView.frame.size
    contentView.backgroundColor = UIColor.gray
    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    return contentView
  }

  @objc func dismissKeyboard() {
    textView1?.dismissKeyboard()
    textView2?.dismissKeyboard()
    textView3?.resignFirstResponder()
  }

  func setTextViewStyle(_ textView: UITextView) {
    textView.font = UIFont.systemFont(ofSize: 20.0)
    textView.autoresizingMask = .flexibleWidth
    textView.layer.cornerRadius = 6.0
  }

  func setTextFieldStyle(_ textView: UITextField) {
    textView.font = UIFont.systemFont(ofSize: 20.0)
    textView.autoresizingMask = .flexibleWidth
    textView.layer.cornerRadius = 6.0
  }

  @objc func resizeView(forKeyboardNotification notification: Notification) {
    let endFrame = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue
    let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber
    let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber

    let statusBarHeight: CGFloat = 20.0
    let landscapeNavBarHeight: CGFloat = 33.0

    if let endFrame = endFrame, let duration = duration, duration != 0 {
      let keyboardFrame = endFrame.cgRectValue
      let orientation = UIApplication.shared.statusBarOrientation
      let oldFrame = view.frame
      var newFrame = oldFrame
      switch orientation {
      case .portrait:
        newFrame = CGRect(x: oldFrame.minX, y: oldFrame.minY,
                          width: oldFrame.width, height: keyboardFrame.minY - view.superview!.frame.minY)
      case .landscapeLeft:
        newFrame = CGRect(x: 0.0, y: 0.0, width: keyboardFrame.height,
                          height: keyboardFrame.minX - landscapeNavBarHeight - statusBarHeight)
      case .landscapeRight:
        let windowWidth = UIApplication.shared.keyWindow?.frame.width ?? 0
        newFrame = CGRect(x: 0.0, y: 0.0, width: keyboardFrame.height,
                          height: windowWidth - landscapeNavBarHeight - statusBarHeight - keyboardFrame.maxX)
      case .portraitUpsideDown:
        break
      default:
        break
      }
      UIView.animate(withDuration: TimeInterval(truncating: duration), delay: 0.0,
                     options: UIViewAnimationOptions(rawValue: UIViewAnimationOptions.RawValue(truncating: curve!)),
                     animations: {() -> Void in
                      self.view.frame = newFrame
      }, completion: nil)
    }
  }

  // MARK: - Responding to Keyman notifications

  private func keyboardPickerDismissed() {
    textView1.becomeFirstResponder()
  }

  func showActivityIndicator() {
    if parent?.view.viewWithTag(-1) != nil {
      return
    }
    let activityView = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
    let containerView = UIView(frame: activityView.bounds.insetBy(dx: -10.0, dy: -10.0))
    containerView.backgroundColor = UIColor(red: 0.0, green: 1.0, blue: 0.0, alpha: 0.75)
    containerView.layer.cornerRadius = 6.0
    containerView.center = view.center
    containerView.tag = -1
    containerView.autoresizingMask =
      [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
    activityView.center = CGPoint(x: containerView.bounds.size.width * 0.5, y: containerView.bounds.size.height * 0.5)
    activityView.startAnimating()
    containerView.addSubview(activityView)
    parent?.view.addSubview(containerView)
  }

  @objc func dismissActivityIndicator() {
    parent?.view.viewWithTag(-1)?.removeFromSuperview()
  }

  @objc func showAlert(_ message: String) {
    let engineBundle = Bundle(for: Manager.self)
    let alertController = UIAlertController(title: NSLocalizedString("alert-download-error-title", bundle: engineBundle, comment: ""),
                                            message: message,
                                            preferredStyle: UIAlertControllerStyle.alert)
    alertController.addAction(UIAlertAction(title: NSLocalizedString("command-ok", bundle: engineBundle, comment: ""),
                                            style: UIAlertActionStyle.default,
                                            handler: nil))
    self.present(alertController, animated: true, completion: nil)
  }
}
