// Copyright 2016 The Tulsi 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 Cocoa
import TulsiGenerator


/// NSTableView that posts a notification when live resizing completes.
final class MessageTableView: NSTableView {
  override func viewDidEndLiveResize() {
    super.viewDidEndLiveResize()

    // Give the delegate a chance to handle the resize now that the live operation is completed.
    NotificationCenter.default.post(name: NSNotification.Name.NSTableViewColumnDidResize,
                                                              object: self)
  }
}


/// View controller for the message output area in the Tulsi wizard.
final class MessageViewController: NSViewController, NSTableViewDelegate, NSUserInterfaceValidations {
  let minRowHeight = CGFloat(16.0)

  @IBOutlet var messageArrayController: NSArrayController!
  @IBOutlet weak var messageAreaScrollView: NSScrollView!

  // Display heights of each row in the message table.
  var rowHeights = [Int: CGFloat]()

  dynamic var messageCount: Int = 0 {
    didSet {
      // Assume that a reduction in the message count means all cached heights are invalid.
      if messageCount < oldValue {
        rowHeights.removeAll(keepingCapacity: true)
      }
      scrollToNewRowIfAtBottom()
    }
  }

  override func loadView() {
    ValueTransformer.setValueTransformer(MessageTypeToImageValueTransformer(),
                                           forName: NSValueTransformerName(rawValue: "MessageTypeToImageValueTransformer"))
    super.loadView()
    bind("messageCount", to: messageArrayController, withKeyPath: "arrangedObjects.@count", options: nil)
  }

  @IBAction func copy(_ sender: AnyObject?) {
    guard let selectedItems = messageArrayController.selectedObjects as? [NSPasteboardWriting], !selectedItems.isEmpty else {
      return
    }

    let pasteboard = NSPasteboard.general()
    pasteboard.clearContents()
    pasteboard.writeObjects(selectedItems)
  }

  @IBAction func clearMessages(_ sender: AnyObject?) {
    (self.representedObject as! TulsiProjectDocument).clearMessages()
  }

  // MARK: - NSUserInterfaceValidations

  func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
    if item.action == #selector(copy(_:)) {
      return !messageArrayController.selectedObjects.isEmpty
    }
    return false
  }

  // MARK: - NSTableViewDelegate

  func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
    if let height = rowHeights[row] {
      return height
    }
    let message = (messageArrayController.arrangedObjects as! [UIMessage])[row]
    let column = tableView.tableColumns.first!
    let cell = column.dataCell as! NSTextFieldCell
    cell.stringValue = message.text
    let bounds = CGRect(x: 0, y: 0, width: column.width, height: CGFloat.greatestFiniteMagnitude)
    let requiredSize = cell.cellSize(forBounds: bounds)
    let height = max(requiredSize.height, minRowHeight)
    rowHeights[row] = height
    return height
  }

  func tableViewColumnDidResize(_ notification: Notification) {
    guard let tableView = notification.object as? NSTableView else { return }
    // Wait until resizing completes before doing a lot of work.
    if tableView.inLiveResize {
      return
    }
    // Disable animation.
    NSAnimationContext.beginGrouping()
    NSAnimationContext.current().duration = 0
    rowHeights.removeAll(keepingCapacity: true)
    let numRows = (messageArrayController.arrangedObjects as AnyObject).count!
    let allRowsIndex = IndexSet(integersIn: 0..<numRows)

    tableView.noteHeightOfRows(withIndexesChanged: allRowsIndex)
    NSAnimationContext.endGrouping()
  }

  // MARK: - Private methods

  private func scrollToNewRowIfAtBottom() {
    guard messageCount > 0,
        let tableView = messageAreaScrollView.documentView as? NSTableView else {
      return
    }

    let lastRowIndex = messageCount - 1

    let scrollContentViewBounds = messageAreaScrollView.contentView.bounds
    let contentViewHeight = scrollContentViewBounds.height

    let newRowHeight = self.tableView(tableView, heightOfRow: lastRowIndex) + tableView.intercellSpacing.height
    let bottomScrollY = tableView.frame.maxY - (contentViewHeight + newRowHeight)

    if scrollContentViewBounds.origin.y >= bottomScrollY {
      tableView.scrollRowToVisible(lastRowIndex)
    }
  }
}


/// Transformer that converts a UIMessage type into an image to be displayed in the message view.
final class MessageTypeToImageValueTransformer : ValueTransformer {
  override class func transformedValueClass() -> AnyClass {
    return NSString.self
  }

  override class func allowsReverseTransformation() -> Bool  {
    return false
  }

  override func transformedValue(_ value: Any?) -> Any? {
    guard let intValue = value as? Int,
          let messageType = TulsiGenerator.LogMessagePriority(rawValue: intValue) else {
      return nil
    }

    switch messageType {
      case .info, .debug, .syslog:
        return NSImage(named: "message_info")
      case .warning:
        return NSImage(named: "message_warning")
      case .error:
        return NSImage(named: "message_error")
    }
  }
}
