#!/usr/bin/ruby -Ke
# -*- coding: utf-8 -*-
#
# おまかせ作図用スクリプト
# 

require 'yaml'
require 'pp'
require "numru/ggraph"
include NumRu
require 'optparse'


# オプション解析
#OPTS = {}
#opt = OptionParser.new
#opt.on('-d', '--dir', 'directory of data files') {|v| OPTS[:d] = v }
#opt.on('-y', '--yml', 'yml file') {|v| OPTS[:y] = v }
#opt.parse!(ARGV)
params = ARGV.getopts('y:','d:')

dir   = params["d"]
yfile = params["y"]
#p dir
#p yfile

###
### データ置き場が指定されていない場合は help を出す.
###
unless dir
  print "Please set options \n"
  print "ruby testrun.rb -d <data dir> -y <YAML file> \n"
  exit
end

###
### YAML ファイルyが指定されていない場合は雛形を作る.
###
unless yfile

  print "Input no YAML file....\n"
  print "Now making sample YAML file....\n"
  sfile = open("sample.yml", 'w')
  sfile.print( "Vars: \n" )

  nfiles0 = Dir.glob("#{dir}*VelX.nc").sort  
  nfiles1 = Dir.glob("#{dir}*PTemp.nc").sort  
  tmp0    = File.basename( nfiles0[0] )
  tmp1    = File.basename( nfiles1[0] )
  prefix  = ""

  # ファイルの接頭詞を取り出す. ファイル名の前方一致.
  100.times{|i|
    unless ( tmp0[0..i] == tmp1[0..i] )
      prefix = tmp0[0..i-1].to_s
      break
    end
  }

  t = Array.new

  nfiles = Dir.glob("#{dir}*.nc").sort
#  p nfiles

  nfiles.each{|nfile|
    # ファイル名から変数名を判断
    tmp = File.basename( nfile )
    /#{prefix}([A-Z].+).nc$/ =~ tmp

    if $1
      var = $1.to_s
      p var

      # ファイルのオープン
      gphys = GPhys::IO.open( nfile, var )

      # 
      rank = gphys.rank
      axis = ""
      rank.times{|j|
        a0 = gphys.coord(j).name
        axis = "#{axis}#{a0}"
        if a0 == "t"
          t.push( gphys.coord(j).to_a )
        end
      }

      sfile.print( " #{var}: \n" )
      sfile.print( "  axis: #{axis} \n" )

      if /xy/ =~ axis
        min1 = gphys.min.to_f.abs
        max1 = gphys.max.to_f.abs
        min2 = gphys.mean('x').mean('y').min.to_f.abs
        max2 = gphys.mean('x').mean('y').max.to_f.abs

        if min1 > max1 
          min_snp = min1 * -1.0
          max_snp = min1
        else
          min_snp = max1 * -1.0
          max_snp = max1
        end

        if min2 > max2
          min_mean = min2 * -1.0
          max_mean = min2
        else
          min_mean = max2 * -1.0
          max_mean = max2
        end       

        if /Cloud$/ =~ var
          sfile.print( "  min_snp: 1.0e-8 \n" )
          sfile.print( "  max_snp: #{sprintf('%.e', max_snp)}\n" )
          sfile.print( "  min_mean: 1.0e-8 \n" )
          sfile.print( "  max_mean: #{sprintf('%.e', max_mean)}\n" )
          sfile.print( "  itr: 3 \n" ) 
        elsif /Rain$/ =~ var
          sfile.print( "  min_snp: 1.0e-8 \n" )
          sfile.print( "  max_snp: #{sprintf('%.e', max_snp)}\n" )
          sfile.print( "  min_mean: 1.0e-8 \n" )
          sfile.print( "  max_mean: #{sprintf('%.e', max_mean)}\n" )
          sfile.print( "  itr: 3 \n" )
        else
          sfile.print( "  min_snp: #{sprintf('%.e', min_snp)}\n" )
          sfile.print( "  max_snp: #{sprintf('%.e', max_snp)}\n" )
          sfile.print( "  min_mean: #{sprintf('%.e', min_mean)}\n" )
          sfile.print( "  max_mean: #{sprintf('%.e', max_mean)}\n" )
          sfile.print( "  itr: 1 \n" )
        end
      else
        min1 = gphys.min.to_f.abs
        max1 = gphys.max.to_f.abs

        if min1 > max1 
          min_mean = min1 * -1.0
          max_mean = min1
        else
          min_mean = max1 * -1.0
          max_mean = max1
        end
        sfile.print( "  min_mean: #{sprintf('%.e', min_mean)}\n" )
        sfile.print( "  max_mean: #{sprintf('%.e', max_mean)}\n" )
        sfile.print( "  itr: 1 \n" )
      end
    end
  }
  sfile.print( "Time: \n" )
  sfile.print( " min: #{t[0].min} \n" )
  sfile.print( " max: #{t[0].max} \n" )
  del0 = t[0][1] - t[0][0]
  fct = (t[0].max - t[0].min) / del0 / 20
  sfile.print( " del: #{del0 * fct.to_i} \n" )

  sfile.print( "Axis: \n" )
  sfile.print( " x: \n" )
  sfile.print( " y: [0.0] \n" )
  sfile.print( " z:  \n" )
  exit
end  

data  = YAML.load_file( yfile )
#pp data

###
### 描画設定
###
DCL.swpset('IWIDTH',  800)
DCL.swpset('IHEIGHT', 800)
#DCL.sgscmn(4)
DCL.sgscmn(10)

DCL.swlset("lwnd",false)
DCL.gropn(4)
DCL.sgpset('lcntl', false)   # 制御文字を解釈しない
DCL.sgpset('lfull',true)     # 全画面表示
DCL.sgpset('lcorner',false)  # コーナーマークを書かない
DCL.uzfact(0.7)              # 座標軸の文字列サイズを定数倍
DCL.sgpset('lfprop',true)    # プロポーショナルフォントを使う
#DCL.udpset('lmsg',false)     # コンター間隔非表示
#DCL.sgpset('lclip',true)     # 枠からはみ出した分を描画しない.

#rmiss = DCL.glpget('rmiss')

###
### 描画
###
comm = Array.new

x = data["Axis"]["x"]
y = data["Axis"]["y"]
z = data["Axis"]["z"]

t0 = data["Time"]["min"]
t1 = data["Time"]["max"]
dt = data["Time"]["del"]
num= ((t1 - t0) / dt).to_i
i = 0

data["Vars"].keys.each{|var|
  p var 

  # ファイルのオープン
  nfiles = Dir.glob("#{dir}*#{var}.nc").sort
  gphys = GPhys::IO.open( nfiles[0], var )  

  itr  = data["Vars"]["#{var}"]["itr"].to_i
  axis = data["Vars"]["#{var}"]["axis"]
  mmax = data["Vars"]["#{var}"]["max_mean"].to_f + 1.0e-8
  mmin = data["Vars"]["#{var}"]["min_mean"].to_f - 1.0e-8
  
  ## 
  ## スナップショット
  ## 
  num.times{|j|
    tn = t0 + dt * j

    if axis == "xyzt"

      smax = data["Vars"]["#{var}"]["max_snp"].to_f + 1.0e-8
      smin = data["Vars"]["#{var}"]["min_snp"].to_f - 1.0e-8
      
      # XZ の二次元
      y.each{|y0|

        GGraph.set_fig('viewport'=>[0.15, 0.85, 0.3, 0.8], 'new_frame'=>true)  

        if itr == 1
          GGraph.tone( gphys.cut( 'y'=> y0 ).cut( 't'=> tn ),
                       true, 
                       'annot'=>false,
                       'max'=> smax, 
                       'min'=> smin
                       )          
        else
          GGraph.tone( ( gphys.cut( 'y'=> y0 ).cut( 't'=> tn ) + 1.0e-10).log10,
                       true, 
                       'annot'=>false,
                       'max'=> -2, 
                       'min'=> -8
                       )          
        end
        GGraph.color_bar('tickintv'=>0, 'voff'=>0.02)
        DCL.uxsttl('b', ".", 1) 
        DCL.uxsttl('b', ".", 1) 
        DCL.uxsttl('b', ".", 1) 
        DCL.uxsttl('b', "#{nfiles[0]}", 1)   
        comm.push("mv dcl_#{sprintf('%03d',i+1)}.png #{var}-XZ_#{sprintf('%08d',y0)}_#{sprintf('%08d',tn)}.png")
        i = i + 1
      }

      # XY の二次元
      if gphys.coord(1).to_a.size > 1
        z.each{|z0|
          GGraph.set_fig('viewport'=>[0.15, 0.85, 0.3, 0.8], 'new_frame'=>true)  
          GGraph.tone( gphys.cut( 'z'=> z0 ).cut( 't'=> tn ),
                       true, 
                       'annot'=>false,
                       'max'=> smax,
                       'min'=> smin
                       )          
          GGraph.color_bar('tickintv'=>0, 'voff'=>0.02)
          DCL.uxsttl('b', ".", 1) 
          DCL.uxsttl('b', ".", 1) 
          DCL.uxsttl('b', ".", 1) 
          DCL.uxsttl('b', "#{nfiles[0]}", 1)   
          comm.push("mv dcl_#{sprintf('%03d',i+1)}.png #{var}-XY_#{sprintf('%08d',z0)}_#{sprintf('%08d',tn)}.png")
          i = i + 1
        }
      end
    end
  }


  if axis == "xyzt"
    # 時系列
    GGraph.set_fig('viewport'=>[0.15, 0.85, 0.3, 0.8], 'new_frame'=>true)  
    GGraph.tone( gphys.mean('x').mean('y'),
                 true, 
                 'annot'=>false,
                 'exchange'=>true,
                 'max'=> mmax, 
                 'min'=> mmin
                 )          
    GGraph.color_bar('tickintv'=>0, 'voff'=>0.02)
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', "#{nfiles[0]}", 1)   
    comm.push("mv dcl_#{sprintf('%03d',i+1)}.png #{var}-mean-XZ.png")
    i = i + 1
    
  elsif axis == "zt"
    
    # 時系列
    GGraph.set_fig('viewport'=>[0.15, 0.85, 0.3, 0.8], 'new_frame'=>true)  
    GGraph.tone( gphys,
                 true, 
                 'annot'=>false,
                 'exchange'=>true,
                 'max'=> mmax, 
                 'min'=> mmin
                   )          
    GGraph.color_bar('tickintv'=>0, 'voff'=>0.02)
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', "#{nfiles[0]}", 1)   
    comm.push("mv dcl_#{sprintf('%03d',i+1)}.png ZZ_#{var}-mean-XZ.png")
    i = i + 1
    
  elsif axis == "t"
    
    # 時系列
    GGraph.set_fig('viewport'=>[0.15, 0.85, 0.3, 0.8], 'new_frame'=>true)  
    GGraph.line( gphys,
                 true, 
                 'annot'=>false,
                 'max'=> mmax, 
                 'min'=> mmin
                 )          
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', ".", 1) 
    DCL.uxsttl('b', "#{nfiles[0]}", 1)   
    comm.push("mv dcl_#{sprintf('%03d',i+1)}.png ZZ_#{var}.png")
    i = i + 1
    
  end
  
}
DCL.grcls

comm.size.times{|i|
  p "#{comm[i]}" 
  system( "#{comm[i]}" ) 
}
