#!/usr/bin/env ruby

=begin

$  for file in *.xwd ; do xwdtopnm ${file} |  pnmcut 2 2 904 654 > test.pnm; ppmtogif test.pnm > ${file}.gif; done
$ gifsicle --delay=50 --no-loop dcl_*.gif > movie.gif

=end

#----------------------------------------------
# ユーザ設定

# 鉛直層 
$layer = 4

# 加熱型 0:linear, 1:positive, 2: noheat
$heat = 0

# 加熱幅 0: control, 1: 4times X half-width
$width = 0

# 加熱タイプ 0: eta1=1.5,eta2=-1.5, 1: eta1=1.5, eta2=0
$eta = 0

# β項 0: beta=0, 1:beta=1
$beta = 1

# 加熱源の中心位置 0: y=0, 1 y=1
$y1shift = "0"

# 次元 0: 2dim, 1: 1dim(初期値1次元問題)
$dim = 0

# 変数 height, u, v
$variable = "height"


# ----------------------------------------------
# プログラムメイン

END{
  
  setopt                 # 引数解析
  set_filename           # ファイル名等基本設定
  wavecisk_anim_main     # gif 作成
  print "gif convert start\n"
  mkgifanim              # gif アニメ作成シェルスクリプト

}

# ----------------------------------------------
# 必要なライブラリ, モジュールの読み込み

require "getopts"
require "numru/netcdf"
module NumRu
  class NetCDFVar
    alias put scaled_put
    alias get scaled_get
  end
end

require "numru/ggraph"
require "colorbar"
include NumRu
include NMath


# ----------------------------------------------
# GPhys メソッド追加定義

def GGraph.annotate(str_ary) # GGraph の annotate メソッド再定義

  charsize = 0.7 * DCL.uzpget('rsizec1')
  dvx = 0.01
  dvy = charsize*1.5
  raise TypeError,"Array expected" if ! str_ary.is_a?(Array)
  vxmin,vxmax,vymin,vymax = DCL.sgqvpt
  vx = 0.66 
#  vy = 0.12 - charsize/2
#  vy = 0.10 - charsize/2
  vy = 0.11 - charsize/2
  str_ary.each{|str|
    DCL::sgtxzv(vx,vy,"[ #{str} ]",charsize,0,-1,1)
    vy -= dvy
  }
  nil
end

class GPhys

  # 座標, データ操作ログ記録関数の定義 (Grid.lost_axes 参照)
  def add_lost_axes( lost )
    GPhys.new( @grid.copy.add_lost_axes( lost.to_a ), @data)
  end
  def set_lost_axes( lost )
    GPhys.new( @grid.copy.set_lost_axes( lost.to_a ), @data)
  end

  # rename 再定義 (gphys class の値を返す)
  def rename(name)
    GPhys.new(@grid,@data.copy.rename(name))
  end

  # attribute 変更再定義 (gphys class の値を返す)
  def set_att(name,val)
    GPhys.new(@grid,@data.copy.set_att(name,val))
  end

end

def cont_lev_set(levels)
  # コンターラベルのデフォルト: (トーンレベル/2 )
  # GPhys のコンター決め打ちオプションが言うこと聞いてくれないので, 
  # なんだか無茶なことをしてる. 
  x  = levels[0]
  dx = levels[3] -levels[2]
  cont_lev  = Array.new
  line_type = Array.new
  (levels.size*2).times{ |num|
    if num % 2 == 0 
      cont_lev.push(levels[num/2])
    else
      cont_lev.push(levels[num/2]+dx/2)
    end
    if cont_lev[num] < 0
      line_type.push(3) 
    else
      line_type.push(1)
    end
  }
  
  label = Array.new
  cont_lev.size.times{ |num|
    label[num] = format("%#.3g", cont_lev[num]).to_s 
    label[num] = "" unless num % 2 == 0
  }
  return cont_lev, line_type, label
end


#----------------------------------------------
# 設定

def set_filename

  heat_ary = ["linear","positive","noheat"]
  width_ary = ["","-4width"]
  eta_ary = ["","-eta1"]
  beta_ary = ["-beta0",""]
  dim_ary = ["","-1dim"]
  y1shift_ary  = ["","-y1shift"]

  $filename = 
    "wavecisk-#{heat_ary[$heat]}#{eta_ary[$eta]}#{beta_ary[$beta]}#{width_ary[$width]}#{y1shift_ary[$y1shift]}#{dim_ary[$dim]}.nc"
#    "wavecisk-#{$layer}layer-#{heat_ary[$heat]}#{width_ary[$width]}.nc"

  print "#{$filename}@#{$variable}\n"

  $gifname =
    "wavecisk-#{heat_ary[$heat]}#{eta_ary[$eta]}#{beta_ary[$beta]}#{width_ary[$width]}#{y1shift_ary[$y1shift]}#{dim_ary[$dim]}-#{$variable}" 
#    "wavecisk-#{$layer}layer-#{heat_ary[$heat]}#{width_ary[$width]}-#{$variable}"

  heat_ary = ["linear","positive_only","no"]
  eta_ary = [
    "eta1 = 1.5, eta2 = -1.5",
    "eta1 = 1.5, eta2 = 0.0"
  ]
  beta_ary = ["beta=0","beta=1"]

  sign = "YU.YAMADA #{Time.now.strftime("%Y/%m/%d %H:%M:%S JST")}"

  $lost_axis = [
    sign,
    "(top) z=1, (bottom) y=0", 
    "rezol: k=l=64, z=#{$layer}", 
    "#{heat_ary[$heat]}_heat, linear_equation", 
    "#{beta_ary[$beta]}, #{eta_ary[$eta]}"
  ]

  $lost_axis.push("init-heat: 4 times X-width") if $width == 1
  $lost_axis.push("init-heat: uniform along the Y-axis") if $dim == 1
  $lost_axis.push("init-heat: shift center position to y0=1") if $y1shift == 1

end


# ----------------------------------------------
# お絵描きメイン

def wavecisk_anim_main


  gphys = GPhys::NetCDF_IO.open($filename, $variable)


  DCL.swpset('LDUMP', true) 
#  DCL.swpset('LALT', true) 
  DCL.swpset('LWAIT',false) ; DCL.swpset('LWAIT0',false) 
  DCL.swpset('LWAIT1',false)
  DCL.swpset('IPOSX', 50) ; DCL.swpset('IPOSY',50)  

  DCL.swpset('LSEP',true)
  DCL.gropn(2)

  DCL.uzfact(0.6)                # 文字の大きさ倍
  DCL.sgpset('lcorner',false)    # コーナーマークはつけない
  DCL.slmgn(0.0, 0.0, 0.0, 0.0)  # 描画マージン指定
  DCL.sgpset('lfprop',true)      # プロポーショナルフォントを使う
  DCL.sgpset('lfull',true)       # 全画面表示
  DCL.sgpset('lcntl', false)     # アンダーバーは普通に表示
  DCL.uscset('cyspos', 'B' )      # y 軸単位を書く位置

  gphys = gphys.set_att("ape_name","#{gphys.data.get_att("long_name")}")
  gphys = gphys.set_att("long_name","").set_att("unit","")

  gphys.grid_copy.axis("t").pos.val.size.times{ |num|

    $file_label = "time = #{num*0.4}"

#    if $variable == "vvel" 
#      plot_def(gphys[true,-51..-11,true,num])
#    else
      plot_def(gphys.cut(true,0,true,true)[true,true,num])
#    end
    GGraph.next_fig('viewport'=>[0.13,0.83,0.483,0.60]) 
    GGraph.next_axes('xunits'=>'','yunits'=>'','xtitle'=>'') 
    g = gphys[true,-51..-11,0,num].set_lost_axes($lost_axis)

    if num == 0 && $variable =~ /vel/ 
      GGraph.tone( g, true ) 
      GGraph.contour( g , false ) 
    else 
      GGraph.tone( g, true , $tone_hash ) 
      GGraph.contour( g , false, $cont_hash ) 

      # タイトル とカラーバー
      DCL::uxsttl("t", "#{$file_label}" , 1.0 )
      DCL::uxmttl("t", gphys.data.get_att("ape_name").gsub("_", " "), -1.0 ) 
      charsize = 0.81 - $file_label.size * 0.0095 
#    DCL::sgtxzv(charsize,0.6,file_label,0.8 * DCL.uzpget('rsizec1'),0,-1,1) 
      DCL::Util::color_bar($cbar_conf)
      
    end

    GGraph.next_axes('xunits'=>'','yunits'=>'','xtitle'=>nil) 
    GGraph.next_fig('viewport'=>[0.13,0.83,0.16,0.443], 'new_frame'=>false )

#    if $variable == "vvel" 
#      plot_def(gphys[true,-51..-11,true,num])
#    else
      plot_def(gphys.cut(true,0,true,true)[true,true,num])
#    end

    g = gphys.cut(true,0,true,true)[true,true,num].set_lost_axes($lost_axis)

    if num == 0 && $variable =~ /vel/ 
      GGraph.tone( g, true ) 
      GGraph.contour( g , false ) 
    else 
      GGraph.tone( g, true , $tone_hash ) 
      GGraph.contour( g , false, $cont_hash ) 
    end
    
  }
  
  DCL::grcls 

end


def tone_set

  levels = NArray[0, 1000e2, 1005e2, 1010e2, 1015e2, 1020e2, 1025e2,1000e3]
  patterns = NArray[30999, 35999, 40999, 55999, 70999, 75999, 85999]
  cont_lev, line_type, label  = cont_lev_set(levels)
  $tone_hash = { 'patterns'=> patterns, 'levels'=>levels }
  $cont_hash = {'levels' => cont_lev, 'index'=> [2,1], 'label'=> label, 
    'line_type'=> line_type }
  $cbar_conf = {
    "levels"=>levels, 
    "colors"=>patterns,
    "eqlev"=>true,
    "nobound"=>0,
    "tick1"=>20,"tick2"=>1
  }

end


# トーン, コンターパターンのデフォルト設定
def plot_def(gphys)
  
  # トーンパターンのデフォルト
  patterns = NArray[30999, 35999, 40999, 55999, 70999, 75999, 85999]
  
  # トーンレベルのデフォルト: ((最大値 - 最小値) / 8 )
=begin
  levels = Array.new
  dx = (gphys.max - gphys.min)/7 ;  x  = gphys.min 
  8.times{ |num| ; levels.push(x) ;  x = dx + x }
  levels[7] = levels[7] + dx ; levels[0] = levels[0] - dx
  levels = NArray.to_na(levels)
  7.times{ |num| 
    if levels[num] < 0 && levels[num+1] > 0 
      if levels[num].abs < levels[num+1].abs
	levels = levels - levels[num]
      else
	levels = levels - levels[num+1]
      end
    end
  }
=end

  dx = (gphys.max - gphys.min)/7
  levels = NArray[-100*dx, -2*dx, -dx, 0.0, dx, 2*dx, 3*dx,100*dx]


  # カラーバーセットのデフォルト: colorbar.rb 参照
  $cbar_conf = {
    "levels"=>levels, 
    "colors"=>patterns,
    "eqlev"=>true, 
    "nobound"=>0, 
    "tick1"=>20,"tick2"=>1
  }
  
  cont_lev, line_type, label  = cont_lev_set(levels)
  
  # コンター, トーンセット
  $tone_hash = { 'patterns'=> patterns, 'levels'=>levels }
  $cont_hash = {'levels' => cont_lev, 'index'=> [2,1], 'label'=> label, 
    'line_type'=> line_type }
  
  # ラインセット
  $line_hash = { 'exchange'=>false }
  
  # window セット
  $fig_set_hash = { "window" => nil }
  
end


# gif アニメ作成シェルスクリプト
def mkgifanim

#  `for file in *.xwd ; do xwdtopnm ${file} |  pnmcut 2 2 904 654 > tmp.pnm; ppmtogif tmp.pnm > ${file}.gif; done >& /dev/null `
#  `gifsicle --delay=50 --loopcount=100 dcl_*.gif > #{$gifname}-anim.gif`
  `mv dcl_001.ps #{$gifname}-t0.ps`
  if File.size?("dcl_151.ps")
    `mv dcl_151.ps #{$gifname}-t60.ps`
  else
    `mv dcl_076.ps #{$gifname}-t30.ps`
  end
  `rm dcl_*`

end

def setopt

  num = 0

  $layer = ARGV[num+1].to_i if num = ARGV.index("-lay")

  # 加熱型 0:linear, 1:positive 2:noheat
  $heat = ARGV[num+1].to_i if num = ARGV.index("-heat")

  # 加熱幅 0: control, 1: 4times X half-width
  $width = ARGV[num+1].to_i if num = ARGV.index("-width")

  # 加熱タイプ 0: eta1=1.5,eta2=-1.5, 1: eta1=1.5, eta2=0
  $eta = ARGV[num+1].to_i if num = ARGV.index("-eta")

  # β項 0: beta=0, 1:beta=1
  $beta = ARGV[num+1].to_i if num = ARGV.index("-beta")

  # 加熱源の中心位置 0: y=0, 1: y=1
  $y1shift = ARGV[num+1].to_i if num = ARGV.index("-y1shift")

  # 次元 0: 2dim, 1: 1dim(初期値1次元問題)
  $dim = ARGV[num+1].to_i if num = ARGV.index("-dim")

  # 変数 height, u, v
  if ARGV.index("-height")
    $variable = "height"
  elsif ARGV.index("-u")
    $variable = "uvel"
  elsif ARGV.index("-v")
    $variable = "vvel"
  end

  if ARGV.index("-h") || ARGV.index("-help") 
    print "
  -lay     num   鉛直層数
  -heat    num   加熱型 0:linear, 1:positive, 2:noheat
  -width   num   加熱幅 0: control, 1: 4times X half-width
  -eta     num   加熱モード 0: eta1=1.5,eta2=-1.5, 1: eta1=1.5, eta2=0
  -beta    num   β項 0: beta=0, 1:beta=1
  -dim     num   次元 0: 2dim, 1: 1dim(初期値1次元問題)
  -y1shift num   加熱源の中心位置 0: y=0, 1: y=1
  -height        出力変数 (height)
  -u             出力変数 (uvel)
  -v             出力変数 (vvel)\n\n"

    exit 1

  end

end


