//
//  Action.swift
//  Keyboard
//
//  Created by ensan on 2020/04/11.
//  Copyright © 2020 ensan. All rights reserved.
//

import CustardKit
import Foundation
import enum KanaKanjiConverterModule.ConverterBehaviorSemantics

public enum BoolOperation: Equatable, Sendable {
    case on, off, toggle
}

public indirect enum ActionType: Equatable, Sendable {
    // テキスト関係
    case input(String, simplyInsert: Bool = false)          // テキストの入力
    case delete(Int)            // テキストの削除
    case smoothDelete           // テキストの一括削除
    case smartDelete(ScanItem)

    case insertMainDisplay(String)   // displayのproxyにテキストをそのまま入力する

    /// クリップボードからペーストする
    ///  - note: フルアクセスがない場合動作しない
    case paste

    // カーソル関係
    case moveCursor(Int)
    case smartMoveCursor(ScanItem)

    case setCursorBar(BoolOperation)
    case enableResizingMode
    // 変換関連
    case enter
    case changeCharacterType(ReplaceBehavior)    // 濁点、半濁点、小さい文字
    case completeCharacterForm([CharacterForm])
    case replaceLastCharacters([String: String])
    case hideLearningMemory
    // タブの変更
    case moveTab(TabData)
    case setTabBar(BoolOperation)
    case setUpsideComponent(UpsideComponent?)
    // キーボードを閉じる
    case dismissKeyboard
    // アプリを開く
    case openApp(String)    // アプリを開く

    // 文字検索
    case setSearchQuery(String, [ConverterBehaviorSemantics.ReplacementTarget])

    // ステート変更
    case setBoolState(String, BoolOperation)
    // case _setBoolState(String, CompiledExpression)

    // 条件分岐アクション
    case boolSwitch(CompiledExpression, trueAction: [ActionType], falseAction: [ActionType])

    // 選択アクション
    case selectCandidate(CandidateSelection)
}

public struct LongpressActionType: Equatable, Sendable {
    public static let none = LongpressActionType()

    /// 実行すべきアクションの存在をチェックする
    public var isEmpty: Bool {
        self.start.isEmpty && self.repeat.isEmpty
    }
    internal init(duration: Duration = .normal, start: [ActionType] = [], repeat: [ActionType] = []) {
        self.duration = duration
        self.start = start
        self.repeat = `repeat`
    }

    public enum Duration: Equatable, Sendable {
        case normal
        case light
    }

    public let duration: Duration
    public let start: [ActionType]
    public let `repeat`: [ActionType]
}
