#!/usr/bin/env ruby

##################################################
=begin
=dcmodel-fig-make

  電脳倶楽部 gpview のラッパー. 
  指定した時間間隔, 一定のコンター間隔で, 
    + 図のプロット
    + ps, png ファイルおよびアニメーション gif の作成. 
      - デフォルトでは ps は gzip 形式で圧縮される. 必要ない場合は --notgz


== USAGE
 
  例えば, 以下のように利用する. 

    % ./dcmodel-fig-make.rb  --delt time --num num  gturl

  コンター間隔を手動で指定する場合には --range オプションを付ける. 

    % ./dcmodel-fig-make.rb  --delt time --num num  --range [min:max] gturl

  ファイル出力する場合には --dump オプションを指定する

    % ./dcmodel-fig-make.rb --delt time --num num --dump gturl

  その他 gpview にそのまま渡したいオプションは, --opt で指定する

    % ./dcmodel-fig-make.rb  --delt time --num num  --opt "--itr 4 --noannotate" gturl 


== OPTION

    --delt            : 出力時間間隔 [必須]

    --num             : 出力枚数
                        デフォルトは 1 

    --range [min:max] : プロットする最小値/最大値の設定
                        指定されていない場合には, 内部的に gturl の
                        最小値と最大値が計算される. 

    --aspect          : 図のアスペクト比の設定

    --int             : 出力開始時刻の設定

    --opt             : gpview にそのまま渡すべきオプションの指定. 

    --delay           : アニメーション gif を作る際の delay. 
                        デフォルトは 40 

    --notgz           : ps を tar で固めて zip しない. 

    --dump            : 図のファイルダンプ

    --nocont          : 2 次元プロットで, コンターを引かない指定


== References

  + http://www.gfd-dennou.org/arch/dcl/dcl-5.3.1/README_pslib
  + http://www.gfd-dennou.org/arch/dcl/dcl-tips/dclpsedit.html


== HISTORY

  2005/12/29   K Sugiyama (created)

=end
##################################################
require "numru/ggraph"
require "getoptlong"
include NumRu

###
### 引数処理
###
parser = GetoptLong.new
parser.set_options(
                   ###    global option   ###
                   ['--num',         GetoptLong::REQUIRED_ARGUMENT],
                   ['--delt',        GetoptLong::REQUIRED_ARGUMENT],
                   ['--range',       GetoptLong::REQUIRED_ARGUMENT],
                   ['--aspect',      GetoptLong::REQUIRED_ARGUMENT],
                   ['--int',         GetoptLong::REQUIRED_ARGUMENT],
                   ['--delay',       GetoptLong::REQUIRED_ARGUMENT],
                   ['--opt',         GetoptLong::REQUIRED_ARGUMENT],
                   ['--dump',        GetoptLong::NO_ARGUMENT],
                   ['--nocont',      GetoptLong::NO_ARGUMENT],
                   ['--notgz',       GetoptLong::NO_ARGUMENT]
                   )
begin
  parser.each_option do |name, arg|
    eval "$OPT_#{name.sub(/^--/, '').gsub(/-/, '_')} = '#{arg}'" 
  end
rescue
  exit(1)
end


###
### エラー処理. delt が設定されていないとダメ. 
###
p "ERROR: --num is not set"    unless $OPT_num
p "ERORR: --delt is not set"   unless $OPT_delt
exit!                          unless $OPT_delt


###
### 内部で用いるコマンドおよびオプションの設定
###
# 時刻の次元名
tunit  = "t"   

#gp コマンド
gpview   = "/usr/bin/gpview"
gpmaxmin = "| /usr/bin/gpmaxmin"  # フィルタとして利用

#dcl 関連 
dclpsrmcm   = "/usr/bin/dclpsrmcm"
dclpsrot    = "/usr/bin/dclpsrot"
dclpsfont   = "/usr/bin/dclpsfont f=H lcntl=1 fact=7000"
dclpsmargin = "/usr/bin/dclpsmargin"
psout       = "dcl.ps"                # dcl の出力する ps ファイル名

# gs 関連. ここで解像度とサイズも設定
gsresolv = "90"
gssize   = "900x600"
gs  = "/usr/bin/gs -sDEVICE=pnmraw -q -dNOPAUSE -dSAFER  -sOutputFile=-" \
      +" -r"+gsresolv+" -g"+gssize

# imagemagic
pnmtopng = "/usr/bin/pnmtopng"
convert  = "/usr/bin/convert"

# tar
tar    = "/bin/tar zcf"
taropt = "--remove-files"

# rm
rm = "/bin/rm"


###
### 変数の設定
###

# 値の初期化
num   = 1
delt  = 0
range = ""
aspect= ""
wsn   = "--wsn 1"
int   = 0.0
opt   = "" 
delay = "-delay 40"  
sint  = ""
cint  = ""
del   = 0.0
maxmin= []
fname = ARGV[0].sub(/\.nc@/,"_").sub(/=/,"").sub(/\,/,"_")

#描画間隔
delt = $OPT_delt.to_i               if $OPT_delt

#描画回数
num = $OPT_num.to_i                 if $OPT_num

# アスペクト比
aspect = "--aspect"+" "+$OPT_aspect if $OPT_aspect

# 図のファイル出力
wsn = "--wsn 2"                     if $OPT_dump

# 描画開始時刻 
int = $OPT_int.to_i                 if $OPT_int

# その他オプション
opt = $OPT_opt                      if $OPT_opt

# delay
delay = "-delay"+" "+$OPT_delay     if $OPT_delay

# 描画範囲の指定. 
if ($OPT_range) 
  range = "--range"+" "+$OPT_range 
else
  # gpmaxmin を用いて最小値と最大値を求める
  gpmaxmin = gpmaxmin+" "+ARGV[0]+","+tunit+"="+int.to_s+":"+(delt*num).to_s
  p gpmaxmin
  fil = open(gpmaxmin)
  fil.each { |line| 
    /["min"|"max"]=(\S+),\s+/ =~ line  # 出力結果から最大値と最小値を探査
    maxmin << $1.to_f if $1
  }
  p maxmin
  range = "--range"+" "+maxmin[1].to_s+":"+maxmin[0].to_s
end

# 色塗り, コンターラインの設定
## 最小値と最大値の差を求める
if ($OPT_range) 
  /(.*):(.*)/ =~ $OPT_range
  del = $2.to_f - $1.to_f
else
  # gpmaxmin の結果から最小値と最大値を求める
  del = maxmin[0] - maxmin[1]
end

## 色分け, コンターの間隔を求める. 色分けは最大値 100 を用いる. 
sdel = del / 99.0
cdel = del / 10.0

## sint, cint の設定
sint = "--sint"+" "+sdel.to_s 
if ($OPT_nocont) 
  cint = "--nocont"
else
  cint = " "
end


# 最大時刻から, 出力時刻のフォーマットを決める
order = Math::log10(delt * num).to_i + 1
fmt = "%0"+(order.to_i).to_s+"d"


###
### 図の出力, ファイル出力
###
for i in 0..num 
  
  # 時刻設定
  time = sprintf(fmt, int+delt*i)

  # 実行コマンドの作成, 実行
  gturl = ARGV[0]+","+tunit+"="+time.to_s   
  p gpview, gturl, range, aspect, wsn, sint, cint, opt
  view = gpview+" "+gturl+" "+range+" "+aspect+" "+wsn+" " \
         +sint+" "+cint+" "+opt
  p view
  system (view)
  
  # ps --> png の変換
  if ($OPT_dump)
    psfile  = fname+"_"+tunit+time.to_s+".ps"
    pngfile = fname+"_"+tunit+time.to_s+".png"
    
    # dcl 付属コマンドを用いて変換
    dclps = dclpsrmcm+" "+psout+" | "+dclpsrot+" | "+dclpsfont+" | " \
            +dclpsmargin+" > "+psfile
    p dclps
    system (dclps)
    
    # ps ファイルを png ファイルに変換
    pspng = gs+" "+psfile+" -c quit| "+pnmtopng+" > "+pngfile
    p pspng
    system (pspng)

    #掃除
    psrm = rm+" dcl.ps"
    system( psrm )
  end  
end


# アニメーション作成, ps ファイル圧縮
if ($OPT_dump)
  giffile  = fname+"_anim.gif"
  pngfiles = fname+"*.png"
  psfiles  = fname+"*.ps"
  tgzfile  = fname+".tar.gz"

  mkanim = convert+" "+delay+" "+pngfiles+" "+giffile
  p mkanim
  system (mkanim)

  unless ($OPT_notgz)
    # tar ファイルに固める
    pstar = tar+" "+tgzfile+" "+psfiles+" "+taropt
    p pstar
    system (pstar)
  end
end
