#########################################################################
##                                                                     ##
##  I N T E R S T E L L A R   C O N S O L E  Media GUI                 ##
##            Copyright (C) 2025- Misato Observatory, Wakayama, Japan  ##
##                                                                     ##
##  This software is available under the GPL (General Public License)  ##
##                                                                     ##
##       Tcl/Tk References: http://www.nct9.ne.jp/m_hiroi/tcl_tk_doc/  ##
##                                                                     ##
#########################################################################


####################################################################
##                                                                ##
##              G E N E R I C   P R O C E D U R E S               ##
##                                                                ##
####################################################################

#
# 汎用: stellariumスクリプトn行 を送信 (可変引数)
#
#  【注意】
#    ・args[n] に空白を入れたい場合は [~] を、["] を入れたい場合は ['] とする。
#      例: "Ursa Major" は 'Ursa~Major' とする
#    ・送信できるのは、関数の羅列だけである。
#      Stellariumがクラッシュするため、for()文などの制御構文を送ってはならない。
#
proc send_ssc_lines_mg { args } {

  global stellarium_direct_url
  global buffer_internal_info_mg

  foreach code1line $args {

    # replace [~] with [ ], and ['] with ["]
    set code_p0 [regsub -all {~} $code1line { }]
    set code_p1 [regsub -all {'} $code_p0 {"}]
    set str_code $code_p1

    set buffer_internal_info_mg $str_code

    # send a code using POST
    do_http_post $stellarium_direct_url "code=$str_code" ret buffer_internal_info_mg

  }

}

#
# 汎用: ISC Serverから読み込み、1行=1要素の配列を array_ret に返す
#
proc get_line_array_from_iscserv_mg { filename_text array_ret } {

  upvar $array_ret array_ref
  global iscserv_url
  global buffer_internal_info_mg

  array set array_ref {}

  do_http_get $iscserv_url/$filename_text ret_string buffer_internal_info_mg

  if { $ret_string eq "" } {
    # do nothing
  } else {
    set lines [split $ret_string "\n"]
    set len_lines [llength $lines]
    set j 0
    for {set i 0} {$i < $len_lines} {incr i} {
      set txt_line [lindex $lines $i]
      set s [string trim $txt_line]
      # skip comments
      if { [string length $s] != 0 && [string index $s 0] ne "#" } {
        set array_ref($j) $s
        incr j
      }
    }
  }

}


####################################################################
##                                                                ##
##                      P R O C E D U R E S                       ##
##                                                                ##
####################################################################

#                                        #
# ここからのprocは特定のウィジェット専用 #
#                                        #

# load and display a sky image
proc display_sky_image { image_id } {

  global flag_sky_image
  global name_sky_image
  global param_sky_image
  global checkbox_sky_image
  global checkbox_flag_sky_image_solo

  if { $checkbox_sky_image($image_id) != 0 } {
    set len_names [array size name_sky_image]
    if { $checkbox_flag_sky_image_solo != 0 } {
      for {set i 0} {$i < $len_names} {incr i} {
        if { $i != $image_id && $checkbox_sky_image($i) != 0 } {
          set checkbox_sky_image($i) 0
          send_ssc_lines_mg "core.removeSkyImage($name_sky_image($i))"
          break
        }
      }
      send_ssc_lines_mg "core.loadSkyImage($name_sky_image($image_id),$param_sky_image($image_id))"
      for {} {$i < $len_names} {incr i} {
        if { $i != $image_id && $checkbox_sky_image($i) != 0 } {
          set checkbox_sky_image($i) 0
          send_ssc_lines_mg "core.removeSkyImage($name_sky_image($i))"
        }
      }
    } else {
      send_ssc_lines_mg "core.loadSkyImage($name_sky_image($image_id),$param_sky_image($image_id))"
    }
  } else {
    send_ssc_lines_mg "core.removeSkyImage($name_sky_image($image_id))"
  }

}

# remove all sky images
proc remove_all_sky_images {} {

  global name_sky_image
  global checkbox_sky_image

  set len_names [array size name_sky_image]

  for {set i 0} {$i < $len_names} {incr i} {
    if { $checkbox_sky_image($i) != 0 } {
      send_ssc_lines_mg "core.removeSkyImage($name_sky_image($i))"
      set checkbox_sky_image($i) 0
    }
  }

}

# destroy media-gui
proc destroy_media_gui { top } {

  if { $top eq "." } {
    remove_all_sky_images
  } else {
    after 1 remove_all_sky_images
  }
  destroy $top

}

#
# media-gui の初期化
# (メインGUIの初期設定「全」を押すと実行される)
#
proc initialize_media_gui {} {

  global checkbox_flag_sky_image_solo

  remove_all_sky_images

  set checkbox_flag_sky_image_solo 0

}

# build GUI of image list
proc build_sky_image_check_list { top filename_text } {

  global font_small
  global stellarium_script_dir
  global config_default_media_dir
  global buffer_internal_info_mg
  global checkbox_sky_image

  global flag_sky_image
  global name_sky_image
  global param_sky_image

  if { 0 < [array size name_sky_image] } {
    remove_all_sky_images
  }

  array set flag_sky_image {}
  array set name_sky_image {}
  array set param_sky_image {}

  array set lines {}

  get_line_array_from_iscserv_mg $filename_text lines

  set len_lines [array size lines]

  #set buffer_internal_info_mg "len_lines = $len_lines"
  #set len_lines 0

  for {set i 0} {$i < $len_lines} {incr i} {
    set lst [split $lines($i) ","]
    if { 6 <= [llength $lst] } {
      set s0 [string trim [lindex $lst 0]]
      set s1 [string trim [lindex $lst 1]]
      if { [string match {[A-Za-z]:[/\\]*} $s1] } {
        set path_s1 [regsub -all {[\\]} $s1 "/"]
      } elseif { [string match {[/\\]*} $s1] }  {
        set path_s1 [regsub -all {[\\]} $s1 "/"]
      } else {
        set path_s1 "$stellarium_script_dir/$config_default_media_dir/$s1"
      }
      set s2 [string trim [lindex $lst 2]]
      set s3 [string trim [lindex $lst 3]]
      set s4 [string trim [lindex $lst 4]]
      set s5 [string trim [lindex $lst 5]]
      set s6 [string trim [lindex $lst 6]]
      if { $s6 eq "" } {
        set s6 "0"
      }
      set s7 [string trim [lindex $lst 7]]
      if { $s7 eq "" } {
        set s7 "2.5"
      }
      set s8 [string trim [lindex $lst 8]]
      if { $s8 eq "" } {
        set s8 "-14"
      }
      set flag_sky_image($i) 0
      set name_sky_image($i) "'$s0'"
      set param_sky_image($i) "'$path_s1',$s3,$s4,$s5,$s6,$s7,$s8,true,'$s2'"
      set checkbox_sky_image($i) 0
      frame $top.fr_cb_sky_image_$i
      ttk::checkbutton $top.cb_sky_image_$i -style Small.TCheckbutton -text "$s0" -variable checkbox_sky_image($i) -command "display_sky_image $i"
      bind $top.cb_sky_image_$i <Return> {event generate %W <Key-space>}
      label $top.cl_sky_image_$i -text "($s1, $s2, $s3, $s4, $s5)" -font $font_small
      pack $top.cb_sky_image_$i -side left -expand 0 -fill x -in $top.fr_cb_sky_image_$i
      pack $top.cl_sky_image_$i -expand 1 -fill x -in $top.fr_cb_sky_image_$i
      pack $top.fr_cb_sky_image_$i -expand 0 -fill x -in $top.lf_sky_image
    }
  }
}


####################################################################
##                                                                ##
##                            M A I N                             ##
##                                                                ##
####################################################################

#
# 動作モード
#
set flag_copy_only 0

#
# 画像・動画が格納されるデフォルトのディレクトリ
#
set config_default_media_dir "media"

#
# ファイル名
#
set filename_list_skyimg "list_sky-image.txt"


####################################################################
##                                                                ##
##                G U I   C O N S T R U C T I O N                 ##
##                                                                ##
####################################################################

set checkbox_flag_sky_image_solo 0

set buffer_internal_info_mg "-"

array set checkbox_sky_image {}
array set flag_sky_image {}
array set name_sky_image {}
array set param_sky_image {}


########################################################################

#
# GUI のオープン
#  top: 新規のtoplevelウィンドウ名。"" の場合は新規に作らず、
#       既存のメインウィンドウを使用する
#  flag_copy_only: 0 以外をセットすると、設定ファイルのコピーのみ実行し、
#                  GUI は作らない（hostの場合のみ）
#
proc open_media_gui { top flag_copy_only } {

  global gui_tsl

  global flag_host_gui
  global stellarium_url
  global iscserv_url
  global config_default_media_dir
  global filename_list_skyimg

  global font_labelframe
  global font_internal
  global buffer_internal_info_mg

  #
  # Host用 GUIの場合、設定ファイルをISC Serverのrootにコピーする
  #
  if { $flag_host_gui != 0 } {

    set iscserv_root [get_stellarium_io_directory]

    set buffer_internal_info_mg "iscserv_root=$iscserv_root"

    # 設定ファイルをコピーする
    set buffer_internal_info_mg "copy: $filename_list_skyimg -> $iscserv_root/."
    file copy -force $config_default_media_dir/$filename_list_skyimg $iscserv_root/$filename_list_skyimg

    if { $flag_copy_only != 0 } {
      if { $top eq "" } {
        exit
      }
      return
    }

  }

  set status 0
  if { $top ne "" } {
    set status [catch {toplevel $top} ret]
  }

  if { $status == 0 } {

    # ウィンドゥ名称,属性の設定
    set title_str "Interstellar Console :: media"
    if { $flag_host_gui != 0 } {
      append title_str " (Host)"
    } else {
      append title_str " ($stellarium_url)"
    }

    if { $top eq "" } {
      wm title . $title_str
      wm resizable . 0 0
    } else {
      wm title $top $title_str
      wm resizable $top 0 0
    }

    ########################################################################

    frame $top.fr_rootwin

    ########################################################################

    labelframe $top.lf_sky_image -text "Sky Image" -font $font_labelframe

    frame $top.fr_label_sky_image

    label $top.l_sky_image -text "$gui_tsl(MEDIAGUI_SELECT_IMAGES)"
    ttk::checkbutton $top.cb_flag_sky_image_solo -style Small.TCheckbutton -text "$gui_tsl(MEDIAGUI_IMG_SOLO)" -variable checkbox_flag_sky_image_solo
    #ttk::button $top.b_sky_image_aoff -style Small.TButton -text "$gui_tsl(MEDIAGUI_IMG_ALL_OFF)" -command "remove_all_sky_images"
    #ttk::button $top.b_sky_image_edit -style Small.TButton -text "$gui_tsl(EDIT)" -command "open_text_editor .edt_skim $config_default_media_dir/$filename_list_skyimg"
    create_button_small $top.b_sky_image_aoff "$gui_tsl(MEDIAGUI_IMG_ALL_OFF)" "remove_all_sky_images"
    create_button_small $top.b_sky_image_edit "$gui_tsl(EDIT)" "open_text_editor .edt_skim $config_default_media_dir/$filename_list_skyimg"
    pack $top.l_sky_image -side left -expand 1 -fill x -in $top.fr_label_sky_image
    pack $top.cb_flag_sky_image_solo $top.b_sky_image_aoff -side left -expand 0 -fill x -in $top.fr_label_sky_image
    if { $flag_host_gui != 0 } {
      pack $top.b_sky_image_edit -side left -expand 0 -fill x -in $top.fr_label_sky_image
    }
    pack $top.fr_label_sky_image -expand 0 -fill x -in $top.lf_sky_image

    # ISC Serverから設定ファイルを読んで GUI を構築する
    build_sky_image_check_list $top $filename_list_skyimg

    if { $top eq "" } {
      bind . <Up> { focus [tk_focusPrev %W] }
      bind . <Down> { focus [tk_focusNext %W] }
      # Xボタン
      wm protocol . WM_DELETE_WINDOW [list destroy_media_gui .]
    } else {
      bind $top <Up> { focus [tk_focusPrev %W] }
      bind $top <Down> { focus [tk_focusNext %W] }
      # Xボタン
      wm protocol $top WM_DELETE_WINDOW [list destroy_media_gui $top]
    }

    pack $top.lf_sky_image -expand 0 -fill x -padx [scaled_px 4] -pady [scaled_px 3] -in $top.fr_rootwin

    ################################################################

    labelframe $top.lf_internal -text "Internal Info" -font $font_labelframe

    entry $top.e_debug -textvariable buffer_internal_info_mg -font $font_internal
    pack $top.e_debug -expand 1 -fill x -in $top.lf_internal

    pack $top.lf_internal -expand 0 -fill x -padx [scaled_px 4] -pady [scaled_px 3] -in $top.fr_rootwin

    ########################################################################

    pack $top.fr_rootwin

  }

  return

}

