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


/// Models a UIRuleEntry as a node suitable for display in the options target selector.
class OptionsTargetNode: UISelectableOutlineViewNode {

  /// Tooltip to be displayed for this node.
  @objc var toolTip: String? = nil

  @objc var boldFont: Bool {
    return !children.isEmpty
  }
}


protocol OptionsTargetSelectorControllerDelegate: class {
  /// Invoked when the target selection has been changed.
  func didSelectOptionsTargetNode(_ node: OptionsTargetNode)
}


// Delegate for the target selector outline view.
class OptionsTargetSelectorController: NSObject, NSOutlineViewDelegate {
  static let projectSectionTitle =
      NSLocalizedString("OptionsTarget_ProjectSectionTitle",
                        comment: "Short header shown before the project in the options editor's target selector.")
  static let targetSectionTitle =
      NSLocalizedString("OptionsTarget_TargetSectionTitle",
                        comment: "Short header shown before the build targets in the options editor's target selector.")

  weak var view: NSOutlineView!
  @objc dynamic var nodes = [OptionsTargetNode]()

  weak var delegate: OptionsTargetSelectorControllerDelegate?
  weak var model: OptionsEditorModelProtocol! = nil {
    didSet {
      if model == nil || model.projectName == nil { return }

      let projectSection = OptionsTargetNode(name: OptionsTargetSelectorController.projectSectionTitle)
      projectSection.addChild(OptionsTargetNode(name: model.projectName!))
      var newNodes = [projectSection]

      if model.shouldShowPerTargetOptions, let targetEntries = model.optionsTargetUIRuleEntries {
        let targetSection = OptionsTargetNode(name: OptionsTargetSelectorController.targetSectionTitle)
        for entry in targetEntries {
          let node = OptionsTargetNode(name: entry.targetName!)
          node.toolTip = entry.fullLabel
          node.entry = entry
          targetSection.addChild(node)
        }
        newNodes.append(targetSection)
      }
      nodes = newNodes

      // Expand all children in the target selector and select the project.
      view.expandItem(nil, expandChildren: true)
      view.selectRowIndexes(IndexSet(integer: 1), byExtendingSelection: false)
    }
  }

  init(view: NSOutlineView, delegate: OptionsTargetSelectorControllerDelegate) {
    self.view = view
    self.delegate = delegate
    super.init()
    self.view.delegate = self
  }

  func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool {
    // The top level items are not selectable.
    return outlineView.level(forItem: item) > 0
  }

  func outlineView(_ outlineView: NSOutlineView, shouldCollapseItem item: Any) -> Bool {
    return false
  }

  func outlineView(_ outlineView: NSOutlineView, shouldShowOutlineCellForItem item: Any) -> Bool {
    return false
  }

  func outlineViewSelectionDidChange(_ notification: Notification) {
    if delegate == nil { return }
    let selectedTreeNode = view.item(atRow: view.selectedRow) as! NSTreeNode
    let selectedTarget = selectedTreeNode.representedObject as! OptionsTargetNode
    delegate!.didSelectOptionsTargetNode(selectedTarget)
  }
}
