# @ts-check

import windowShell_endsWith from './endsWith'
import windowShell_noop from './noop'

class WindowShell

  ###* @type import('./windowShell').Constructor ###
  constructor: (exe, title = '') ->

    ###* @type import('./windowShell').WindowShell['exe'] ###
    @exe = ''
    if windowShell_endsWith exe, '.exe' then @exe = exe
    else @exe = "#{exe}.exe"

    ###* @type import('./windowShell').WindowShell['title'] ###
    @title = ''
    if title then @title = title

  ###* @type import('./windowShell').WindowShell['getWindowIdString'] ###
  getWindowIdString: ->
    windowShell_id = @getWindowId()
    unless windowShell_id then return ''

    return "ahk_id #{windowShell_id}"

  ###* @type import('./windowShell').WindowShell['blur'] ###
  blur: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    # 实际上是聚焦任务栏
    name = 'ahk_class Shell_TrayWnd'
    windowShell_noop name
    Native 'WinActivate, %name%'
    return

  ###* @type import('./windowShell').WindowShell['close'] ###
  close: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinClose, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['focus'] ###
  focus: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinActivate, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['getBounds'] ###
  getBounds: ->
    [windowShell_x, windowShell_y, windowShell_w, windowShell_h] = [0, 0, 0, 0]

    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return {
      x: windowShell_x
      y: windowShell_y
      width: windowShell_w
      height: windowShell_h
    }

    Native 'WinGetPos, windowShell_x, windowShell_y, windowShell_w, windowShell_h, % windowShell_idString'
    return {
      x: windowShell_x
      y: windowShell_y
      width: windowShell_w
      height: windowShell_h
    }

  ###* @type import('./windowShell').WindowShell['getProcessId'] ###
  getProcessId: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return 0

    windowShell_pid = 0
    Native 'WinGet, windowShell_pid, PID, % windowShell_idString'
    return windowShell_pid

  ###* @type import('./windowShell').WindowShell['getTitle'] ###
  getTitle: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return ''

    if @title then return @title

    windowShell_title = ''
    Native 'WinGetTitle, windowShell_title, % windowShell_idString'
    return windowShell_title

  ###* @type import('./windowShell').WindowShell['getWindowId'] ###
  getWindowId: ->
    windowShell_id = 0
    windowShell_selector = ''
    windowShell_noop windowShell_selector

    if @title then windowShell_selector = "#{@title} ahk_exe #{@exe}"
    else windowShell_selector = "ahk_exe #{@exe}"

    Native 'WinGet, windowShell_id, ID, % windowShell_selector'

    return windowShell_id

  ###* @type import('./windowShell').WindowShell['hide'] ###
  hide: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinHide, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['isActive'] ###
  isActive: ->
    windowShell_id = @getWindowId()
    unless windowShell_id then return false

    windowShell_activeId = WinActive "ahk_id #{windowShell_id}"
    return windowShell_activeId == windowShell_id

  ###* @type import('./windowShell').WindowShell['isExists'] ###
  isExists: ->
    windowShell_id = @getWindowId()
    return windowShell_id > 0

  ###* @type import('./windowShell').WindowShell['isFullScreen'] ###
  isFullScreen: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return false

    { x, y, width, height } = @getBounds()
    return x == 0 and y == 0 and width == A_ScreenWidth and height == A_ScreenHeight

  ###* @type import('./windowShell').WindowShell['kill'] ###
  kill: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinKill, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['maximize'] ###
  maximize: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinMaximize, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['minimize'] ###
  minimize: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinMinimize, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['restore'] ###
  restore: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinRestore, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['setPriority'] ###
  setPriority: (level) ->
    windowShell_id = @getWindowId()
    unless windowShell_id then return

    windowShell_noop level
    Native 'Process, Priority, % this.exe, % level'
    return

  ###* @type import('./windowShell').WindowShell['setStyle'] ###
  setStyle: (style) ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    windowShell_noop style
    Native 'WinSet, Style, % style, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['show'] ###
  show: ->
    windowShell_idString = @getWindowIdString()
    unless windowShell_idString then return

    Native 'WinShow, % windowShell_idString'
    return

  ###* @type import('./windowShell').WindowShell['wait'] ###
  wait: (callback) ->
    windowShell_selector = ''
    windowShell_noop windowShell_selector

    if @title then windowShell_selector = "#{@title} ahk_exe #{@exe}"
    else windowShell_selector = "ahk_exe #{@exe}"

    Native 'WinWait, % windowShell_selector'

    if callback then callback()
    return

windowShell_noop WindowShell