#! /usr/bin/env tclsh
# -*- tcl -*- 
#######################################################
#     This is the boiler plate code                    #
########################################################
# This bit of code figures out where the rest of the   #  
# routines are on the assumption that they are in the  #
# same directory as the initial code file.             #
# If 'setIt' is 1 or not coded auto_path is set in any #
# case the resulting dir is returned to the caller     #
# A second dir is also returned, which is the same     #
# with a leading C:/ removed as required by Wrap code  # 
# for windows. If not windows the two will be the same.#
#                                                      #
# To function correctly this code MUST be called prior #
# to completion of the 'source' command that brings it #
# in. Also, since it is used to set up auto_path it    #
# can not be auto loaded.  It may be sourced, but      #
# again the from where issue is there.                 #
#                                                      #
# It is best if this is just merger with the using     #
# code in a location prior to its call.                #
#                                                      #
proc setAutoPath {{setIt 1}} {
  set it [info script]
  set it [expr {$it == "" ? "[pwd]/*" : $it}]
  set it [file dir [file dir [file norm $it/*]]]
  # Wrap code requires we not have the drive letter...
  if {$setIt} {
    lappend ::auto_path $it [regsub {^[a-zA-Z]:/} $it {/}]
  }
  return [list $it [regsub {^[a-zA-Z]:/} $it {/}]]
}
##########################################################
#            End of boiler plate code                    #
##########################################################
setAutoPath
if {0} { ; # set to 1 to debug
  lappend auto_path [file norm ../]
  setupDebug 1
  frputs "[info script] [setAutoPath] "
} else {
  proc frputs {args} {}
}
set MSW [expr {$::tcl_platform(platform) == "windows"}]

set convertProg [expr {$MSW ? "magick convert" : "convert"}]
# 
# a simple scrip to build the icons given a master file
# invokation: make_icons 'seed' 'prog' where 'seed' is a master '*.png' of the icon
# seed should be at least 256x256.
# and prog is the program name
#
# we build these sizes for *nix
set sizes {16  32 48 128 256}

# will put these sizes in the .ico file
set MSsizes {16 32 48 128 256}
proc setupEnv {} {
  # set seed [lindex $argv 0]
  puts "argv is =$::argv<"
  lassign $::argv ::seed ::prog
  puts "seed is $::seed"

  if {$::prog == {}} {
    puts "Oops!  need a 'program name' (parameter 2)"
    exit 1
  }
  if {![file exists ../icons]} {
    file mkdir ../icons
  }
  cd ../icons
  set ::icondir [pwd]
  if {![file exists $::seed]} {
    puts "Oops!  need a seed file that exists, not \{$::seed\}"
    exit 1
  }
  puts "seed is $::seed"
}
cd ../icons

proc saveOld {} {
  while {[file exists iconbackup_[incr foo]]} {}
  set dir [file normalize iconbackup_$foo]
  puts "Saving old files in $dir"
  file mkdir $dir

  foreach f [glob -nocomplain filerunner-*.png] {
    file rename $f ${dir}/$f
  }
}
proc buildPngFiles {} {
  cd $::icondir
  foreach sz $::sizes {
    puts "Building $::prog-${sz}x${sz}.png"
    # exec $convertProg $seed -resize ${sz}x${sz} BMP3:$::prog-${sz}x${sz}.bmp
    exec {*}$::convertProg $::seed -resize ${sz}x${sz} $::prog-${sz}x${sz}.png
  }
}
# get the greatest common divisor

proc gcd {num1 num2} {
  while {[set tmp [expr {$num1%$num2}]]} {
    set num1 $num2
    set num2 $tmp
  }
  return $num2
}
# resize an image 'from' to 'to' where 'from' and 'to' are intergers
proc resize {img from to} {
  set gcd [gcd $from $to]
  set from [expr {$from / $gcd}]
  set to   [expr {$to   / $gcd}]
  frputs from to
  if {$from == $to} {return}
  image create photo tmp_img
    
  tmp_img copy $img -zoom $to
  $img blank
  $img copy tmp_img -subsample $from -shrink
  image delete tmp_img
}

# For windows wrap useto want and now wants:
# 16x16  16 colors            16x16 16 & 256
# 32x32  16 & 2 & 256         32x32 4-bit & 8-bit & 24-bit
#                             48x48 4-bit & 8-bit & 24-bit
#                             128x128 24-bit
#                             256x256 24-bit

# we add:
# 48X48   16
# 256x256 16
#
# and all icons and in one file

set windowsops [list \
		    {16 4} {16 8} \
		    {32 4} {32 8} {32 24}\
		    {48 4} {48 8} {48 24}\
		    {128 24} {256 24}
		   ]

package require img::bmp
package require img::ico

proc buildIcon {} {
  set ::files {}
  cd $::icondir
  image create photo master -format bmp -file $::seed -height 256 -width 256
  set cmd "$::convertProg $::seed -bordercolor white -border 0  "
  foreach size $::windowsops {
    lassign $size sz bpp
    set filNam "$::prog-icons-$sz-$bpp.ico"
    if {$bpp != 24} {
      set colors [expr {$bpp * $bpp}]
      
      set cmdApend " -verbose -resize ${sz}x$sz -colors $colors -depth $bpp $filNam"
      puts "Trying: $cmdApend"
      set r [catch "exec [regsub -all {\\} $cmd$cmdApend {\\\\}]" out]
      puts "$out"
      # if {$r != 0} {
      # 	puts "$::errorInfo"
      # }
    } else {
      # We require a bpp 24 seed.
      set filNam "$::prog-icons-$sz-$bpp.bmp"
      
      image create photo my_tmp
      my_tmp blank
      my_tmp copy master 
      resize my_tmp 256 $sz
      my_tmp write $filNam -format bmp
      #my_tmp delete
    }
    lappend ::files $filNam
  }
}
  # lets combine them into an ico file
proc combineIco {} {
  set n -1
  foreach file $::files {
    puts "copy $file to $::prog.ico"
    ::ico::copyIcon $file 0 $::prog.ico [incr n]
  }
}
proc cleanUp {} {
  puts "clean up"
  cd $::icondir
  foreach size $::files {
    file delete $size
  }
  foreach sz $::sizes {
  #file delete $prog-${sz}x${sz}.bmp
  }
}
  proc doAll {} {
    setupEnv
    saveOld
    buildPngFiles
    buildIcon
    combineIco
    cleanUp
}
doAll