#!/usr/bin/env ruby

tmp = $LOAD_PATH.dup
$LOAD_PATH[0] = File.dirname($0)
tmp.length.times{|i| $LOAD_PATH[i+1] = tmp[i]}

$VERBOSE = nil

require "numru/gphys"
require "numru/dcl"
require "numru/gave/gave_config"
require "numru/gave/draw"

GAVE_VERSION = "1.1.3"

begin
  require "gettext"
  include GetText
  gettext_path = DATA_PATH+"/locale"
  bindtextdomain("gave",gettext_path,nil,charset="UTF-8")
rescue LoadError
  def _(str) str end
end

module NumRu
  class GPhys
    alias :_initialize :initialize
    def initialize(*arg)
      _initialize(*arg)
      @funcs = Array.new
    end
    alias_method( "_slice".intern, "[]".intern)
    def [](*slicer)
      obj = self._slice(*slicer)
      obj.funcs = self.funcs
      return obj
    end
    alias :_cut :cut
    def cut(*args)
      obj = self._cut(*args)
      obj.funcs = self.funcs
      return obj
    end
    def funcs
      @funcs.dup
    end
    attr_writer :funcs
  end
end

include NumRu

if !defined?(DCL.gtk_version)
  def DCL.gtk_version
    return [1]
  end
end

if DCL.gtk_version[0]==1 then
  require "gtk"
  require "gdk_pixbuf"
  module Gtk
    class Widget
      def set_size_request(*arg); set_usize(*arg); end
      def set_resizable(tf); set_policy(tf,tf,tf); end
      def set_resizable_and_shrink(tfr,tfs); set_policy(tfs,tfr,tfr); end
    end
    class Window
      def active?
	!visible?
      end
      def add_accel_group(accel)
	accel.attach(self)
      end
    end
    class Entry
      def text; get_text; end
      def text=(str); set_text(str.to_s); end
    end
    class ToggleButton
      def add_xpm(xpm, window)
	pix, mask = Gdk::Pixmap.create_from_xpm_d(window, nil, xpm)
	pixmap = Gtk::Pixmap.new(pix, mask)
	self.add(pixmap)
      end
    end
    class Label
      def selectable=(dummy) end
      def justify=(arg) set_justify(arg) end
      def wrap=(arg) set_line_wrap(arg) end
    end
    class Justification
      CENTER = Gtk::JUSTIFY_CENTER
    end
    class ItemFactory
      STOCK_ITEM = ITEM
      alias _create_items create_items
      def create_items(ary)
	ary2 = ary.collect{|a| [ a[0], a[2], a[1], a[4], a[5] ] }
        _create_items(ary2)
      end
      alias _create_item create_item
      def create_item(*ary,&proc)
        _create_item(ary[0],ary[2],ary[1],&Proc.new{|w| proc.call(ary[4],w)})
      end
    end
    class Stock
      OPEN = nil
      SAVE = nil
      QUIT = nil
    end
    class FileSelection
      def set_select_multiple(dummy); self; end
      def selections; [filename]; end
    end
  end
  class List
    def initialize
      @clist = Gtk::CList.new([_("name"),_("value")])
      @clist.set_usize(300,200)
      @clist.set_column_width(0,100)
    end
    def set_item(name, value)
      @clist.append([name, value])
    end
    def add_note(note, title)
      note.append_page_menu(@clist.show, Gtk::Label.new(title), Gtk::Label.new(title))
    end
  end
  TOPLEVEL = Gtk::WINDOW_TOPLEVEL

elsif DCL.gtk_version[0]==2 then
  require "gtk2"
  require "numru/gave/fileselection"
  if defined?(DFileSelection)
    class DRbObject
      alias :_initialize :initialize
      def initialize(*arg)
        _initialize(*arg)
        @funcs = Array.new
      end
      def funcs
        @funcs.dup
      end
      attr_writer :funcs
    end
  end

  module Gtk
    class Widget
      def set_resizable_and_shrink(tfr,tfs); set_resizable(tfr).set_allow_shrink(false); end
    end
    class ToggleButton
      def add_xpm(xpm, dummy)
	image = Gtk::Image.new(Gdk::Pixbuf.new(xpm))
	self.add(image)
      end
    end
  end
  class List
    def initialize
      @model = Gtk::ListStore.new(String, String)
    end
    def set_item(name, value)
      iter = @model.append
      iter[0] = name
      iter[1] = value
    end
    def add_note(note, title)
      treeview = Gtk::TreeView.new(@model)
      treeview.append_column(Gtk::TreeViewColumn.new("name", Gtk::CellRendererText.new, {:text => 0}))
      treeview.append_column(Gtk::TreeViewColumn.new("value", Gtk::CellRendererText.new, {:text => 1}))
      note.append_page(treeview.show, Gtk::Label.new(title))
    end
  end
  TOPLEVEL = Gtk::Window::TOPLEVEL
  Gtk.init
end


class Select_value
  attr_reader :index, :box
  def initialize(val)
    height=20
    @val = val
    @max = val.length-1
    @index = 0
    entry = Gtk::Entry.new
    entry.set_size_request(50,height)
    entry.set_editable(false)
    entry.set_text(val[0].to_s)
    @adjustment = Gtk::Adjustment.new(0,0,@max+1,1,10,1)
    @adjustment.signal_connect("value-changed"){|w|
      @index=w.value.round
      entry.set_text(val[@index].to_s)
    }
    @scale = Gtk::HScale::new(@adjustment)
    @scale.set_size_request(150,height)
    @scale.set_draw_value(false)
    @box = Gtk::HBox.new(false,0)
    @box.pack_start(entry, true, true, 0 )
    @box.pack_start(@scale)
    @box.set_sensitive(false)
  end
  def active; @box.set_sensitive(true); end
  def not_active; @box.set_sensitive(false); end
  def next
    if @index < @max then
      @adjustment.value = @index+1
    else
      @adjustment.value = 0
    end      
  end
  def val
    @val
  end
end

class Var_select < Gtk::Combo
  def initialize
    super
    entry.set_editable(false)
    not_active
  end
  def get; entry.text; end
  def set(array); set_popdown_strings(array); end
  def set_text(text); entry.text=text; end
  def active; set_sensitive(true); end
  def not_active
    set_sensitive(false)
    entry.set_text(_("cannot select"))
  end
  def signal; entry.signal_connect("changed"){yield};  end
#  def signal; entry.signal_connect("activate"){yield};  end
end


# draw tyep constant
LINE = 0
CONTOUR = 1
MAP = 2
VECTOR = 3

FUNC = 10
Funcs1 = ["mean","stddev","max","min"]
SFunc  = {"mean"=>_("mean"),"stddev"=>_("stddev"),"max"=>_("max"),"min"=>_("min")}

class String
  alias :_to_f :to_f
  def to_f
    if self==""
      return false
    else
      return self._to_f
    end
  end
end

class GAVE

  def min(x,y)
    x<y ? x : y
  end

  attr_accessor :autodraw
  def initialize
    @autodraw = false

    @vars = Hash.new
    @dims = Hash.new

    accel = Gtk::AccelGroup.new

# FileSelection
    fs = Gtk::FileSelection.new("")
    fs.ok_button.signal_connect("clicked"){|w|
      fs.hide
      @filecall.call(fs.selections)
    }
    fs.cancel_button.signal_connect("clicked"){fs.hide}

    if defined?(DFileSelection)
      dfs = DFileSelection.new("Open druby")
      dfs.ok_button.signal_connect("clicked"){|w|
        dfs.hide
        file_open(dfs.selection)
      }
    end

# sub windows
    @subwindows = Array.new
    var_window = Gtk::Window.new(TOPLEVEL).set_title(_("Variable")).set_resizable(false)
    @subwindows.push var_window
    axis_window = Gtk::Window.new(TOPLEVEL).set_title(_("Axis")).set_resizable(false)
    @subwindows.push axis_window
    @dims_window = Gtk::Window.new(TOPLEVEL).set_title(_("Dimensions")).set_resizable(false) #set_policy(false,false,true)
    @subwindows.push @dims_window
    attr_window = Gtk::Window.new(TOPLEVEL).set_title(_("Attributes")).set_resizable_and_shrink(true,false) #set_policy(false,true,false)
    @subwindows.push attr_window
    movie_window = Gtk::Window.new(TOPLEVEL).set_title(_("Movie")).set_resizable(false)
    @subwindows.push movie_window
    map_window = Gtk::Window.new(TOPLEVEL).set_title(_("Map")).set_resizable(false)
    @subwindows.push map_window
    cont_window = Gtk::Window.new(TOPLEVEL).set_title(_("Parameter for Contour and Tone")).set_resizable(false)
    @subwindows.push cont_window
    vector_window = Gtk::Window.new(TOPLEVEL).set_title(_("Parameter for Vector")).set_resizable(false)
    @subwindows.push vector_window
    div_window = Gtk::Window.new(TOPLEVEL).set_title(_("Division")).set_resizable(false)
    @subwindows.push div_window
    p_w = Proc.new{|c,w| c.set_active(false); w.hide }
    var_window.signal_connect("delete-event"){|w,e| p_w.call(@check_var,w) }
    axis_window.signal_connect("delete-event"){|w,e| p_w.call(@check_axis,w) }
    @dims_window.signal_connect("delete-event"){|w,e| p_w.call(@check_dims,w) }
    attr_window.signal_connect("delete-event"){|w,e| p_w.call(@check_attr,w) }
    movie_window.signal_connect("delete-event"){|w,e| p_w.call(@check_movie,w) }
    map_window.signal_connect("delete-event"){|w,e| p_w.call(@check_map,w) }
    cont_window.signal_connect("delete-event"){|w,e| p_w.call(@check_level,w) }
    vector_window.signal_connect("delete-event"){|w,e| p_w.call(@check_vector,w) }
    div_window.signal_connect("delete-event"){|w,e| p_w.call(@check_div,w) }

# Variable window
    @title_entry = Gtk::Entry.new
    @miss_entry = Gtk::Entry.new
    table = Gtk::Table.new(2,2,false)
    table.attach(Gtk::Label.new(_("title")),0,1,0,1)
    table.attach(@title_entry,1,2,0,1)
#    table.attach(Gtk::Label.new(_("missing value")),0,1,1,2)
#    table.attach(@miss_entry,1,2,1,2)
    var_window.add(table.show_all)

# Axis window
    @logxbutton = Gtk::CheckButton.new(_("log scale"))
    @x_title = Gtk::Entry.new
    @x_unit = Gtk::Entry.new
    @x_min = Gtk::Entry.new
    @x_max = Gtk::Entry.new
    table = Gtk::Table.new(2,5,false)
    table.attach(@logxbutton,1,2,0,1)
    table.attach(Gtk::Label.new(_("title")),0,1,1,2)
    table.attach(@x_title,1,2,1,2)
    table.attach(Gtk::Label.new(_("unit")),0,1,2,3)
    table.attach(@x_unit,1,2,2,3)
    table.attach(Gtk::Label.new(_("min")),0,1,3,4)
    table.attach(@x_min,1,2,3,4)
    table.attach(Gtk::Label.new(_("max")),0,1,4,5)
    table.attach(@x_max,1,2,4,5)
    @x_frame = Gtk::Frame.new(_("X-Axis"))
    @x_frame.add(table)

    @logybutton = Gtk::CheckButton.new(_("log scale"))
    @y_title = Gtk::Entry.new
    @y_unit = Gtk::Entry.new
    @y_min = Gtk::Entry.new
    @y_max = Gtk::Entry.new
    table = Gtk::Table.new(2,5,false)
    table.attach(@logybutton,1,2,0,1)
    table.attach(Gtk::Label.new(_("title")),0,1,1,2)
    table.attach(@y_title,1,2,1,2)
    table.attach(Gtk::Label.new(_("unit")),0,1,2,3)
    table.attach(@y_unit,1,2,2,3)
    table.attach(Gtk::Label.new(_("min")),0,1,3,4)
    table.attach(@y_min,1,2,3,4)
    table.attach(Gtk::Label.new(_("max")),0,1,4,5)
    table.attach(@y_max,1,2,4,5)
    @y_frame = Gtk::Frame.new(_("Y-Axis"))
    @y_frame.add(table)
    axisbox = Gtk::VBox.new
    axisbox.pack_start(@x_frame)
    axisbox.pack_start(@y_frame)
    axis_window.add(axisbox.show_all)

# Attributes window
    @attr_note = Gtk::Notebook::new()
    @attr_note.set_tab_pos(Gtk::POS_TOP)
    @attr_note.set_size_request(300, 200)
    box = Gtk::VBox.new(false,0)
    box.pack_start(@attr_note)
    attr_window.add(box.show_all)

# Movie winsow
    start_xpm = ["11 11 2 1",  "  c None", "+  c black",
      "+          ",
      "+++        ",
      "+++++      ",
      "+++++++    ",
      "+++++++++  ",
      "+++++++++++",
      "+++++++++  ",
      "+++++++    ",
      "+++++      ",
      "+++        ",
      "+          "]
    stop_xpm = ["11 11 2 1", "   c None", "+  c black",
      "           ",
      " +++++++++ ",
      " +++++++++ ",
      " +++++++++ ",
      " +++++++++ ",
      " +++++++++ ",
      " +++++++++ ",
      " +++++++++ ",
      " +++++++++ ",
      " +++++++++ ",
      "           "]
    rec_xpm = ["11 11 2 1", "   c None", "+  c red",
      "    +++    ",
      "  +++++++  ",
      " +++++++++ ",
      " +++++++++ ",
      "+++++++++++",
      "+++++++++++",
      "+++++++++++",
      " +++++++++ ",
      " +++++++++ ",
      "  +++++++  ",
      "    +++    "]
    @movie = false
    @movie_step = 1.0
    @rec = false
    @fnum = "001"
    movie_window.realize
    start_button = Gtk::ToggleButton.new
    start_button.add_xpm(start_xpm, movie_window.window)
    stop_button = Gtk::ToggleButton.new
    stop_button.add_xpm(stop_xpm, movie_window.window)
    rec_button = Gtk::ToggleButton.new
    rec_button.add_xpm(rec_xpm, movie_window.window)
    start_button.signal_connect("clicked"){|w|
      if w.active? then
	@time = Time.now
	@movie = Gtk.idle_add{
	  if Time.now - @time > @movie_step then
	    draw_next
	    if @rec then
	      @draw.save_image("dcl"+@fnum+".png")
	      @fnum.next!
	    end
	    @time = Time.now
	  end
	  true
	}
      else
	Gtk.idle_remove(@movie)
      end
    }
    stop_button.signal_connect("clicked"){
      if start_button.active? then
	start_button.set_active(false)
	Gtk.idle_remove(@movie)
      end
    }
    rec_button.signal_connect("clicked"){|w|
      @rec = w.active?
    }
    @movie_combo = Gtk::Combo.new.set_size_request(50,30)
    @movie_combo.entry.set_editable(false)
    @movie_combo.entry.set_text("-")
    box1 = Gtk::HBox.new(false,0)
    box1.pack_start(@movie_combo)
    box1.pack_start(start_button)
    box1.pack_start(stop_button)
    box1.pack_start(rec_button)
    adjustment = Gtk::Adjustment.new(@movie_step,0.0,3,0.1,1,1)
    adjustment.signal_connect("value-changed"){|w|
      @movie_step=w.value
    }
    scale = Gtk::HScale.new(adjustment)
    scale.set_size_request(150,30)
    scale.set_update_policy(Gtk::UPDATE_DELAYED)
    scale.set_draw_value(false)
    box2 = Gtk::HBox.new(false,0)
    box2.pack_start(Gtk::Label.new(_("fast")))
    box2.pack_start(scale)
    box2.pack_start(Gtk::Label.new(_("slow")))
    @movie_box = Gtk::VBox.new(false,0)
    @movie_box.pack_start(box1)
    @movie_box.pack_start(box2)
    movie_window.add(@movie_box.show_all)

# Map window
    @map_type =  [_("ORTHOGRAPHIC"),_("POLAR STEREO"),_("AZIMUTHAL"),_("AZIMUTHAL EQ. AREA")]
    @map_combo = Gtk::Combo.new
    @map_combo.entry.set_editable(false)
    @map_combo.set_popdown_strings(@map_type)
    @pole_lon = Gtk::Entry.new
    @pole_lat = Gtk::Entry.new
    @pole_rot = Gtk::Entry.new
    table = Gtk::Table.new(2,3,false)
    table.attach(Gtk::Label.new(_("longitude")),0,1,0,1)
    table.attach(@pole_lon,1,2,0,1)
    table.attach(Gtk::Label.new(_("latitude")),0,1,1,2)
    table.attach(@pole_lat,1,2,1,2)
    table.attach(Gtk::Label.new(_("rotation")),0,1,2,3)
    table.attach(@pole_rot,1,2,2,3)
    pole_frame = Gtk::Frame.new(_("Pole"))
    pole_frame.add(table)
    @map_check = Gtk::CheckButton.new(_("draw map")).set_active(true)
    box = Gtk::VBox.new(false,0)
    box.pack_start(@map_combo)
    box.pack_start(pole_frame.show_all)
    box.pack_start(@map_check)
    map_window.add(box.show_all)

# Level window
    @cont_min_entry = Gtk::Entry.new
    @cont_interval_entry = Gtk::Entry.new
    cont_manual_box = Gtk::HBox.new.set_sensitive(false)
    cont_manual_box.pack_start(Gtk::Label.new(_("min")))
    cont_manual_box.pack_start(@cont_min_entry)
    cont_manual_box.pack_start(Gtk::Label.new(_("interval")))
    cont_manual_box.pack_start(@cont_interval_entry)
    cont_auto_radio = Gtk::RadioButton.new(_("auto"))
    cont_manual_radio = Gtk::RadioButton.new(cont_auto_radio,_("manual"))
    cont_auto_radio.signal_connect("toggled"){|w|
      cont_manual_box.set_sensitive(false)
      @cont_level = false
    }
    cont_manual_radio.signal_connect("toggled"){|w|
      cont_manual_box.set_sensitive(true)
      @cont_level = true
    }
    cont_int_box = Gtk::HBox.new
    cont_int_box.pack_start(cont_auto_radio)
    cont_int_box.pack_start(cont_manual_radio)
    cont_int_box.pack_start(cont_manual_box)
    @cont_draw_button = Gtk::CheckButton.new(_("draw")).set_active(true)
    @cont_draw_button.signal_connect("toggled"){|w|
      cont_int_box.set_sensitive(w.active?)
    }
    cont_table = Gtk::Table.new(2,3,false)
    cont_table.attach(Gtk::Label.new(_("Contour")),0,2,0,1)
    cont_table.attach(@cont_draw_button,1,2,1,2)
    cont_table.attach(Gtk::Label.new(_("Contour")+" "+_("interval")),0,1,2,3)
    cont_table.attach(cont_int_box,1,2,2,3)

    @tone_min_entry = Gtk::Entry.new
    @tone_interval_entry = Gtk::Entry.new
    tone_manual_box = Gtk::HBox.new.set_sensitive(false)
    tone_manual_box.pack_start(Gtk::Label.new(_("min")))
    tone_manual_box.pack_start(@tone_min_entry)
    tone_manual_box.pack_start(Gtk::Label.new(_("interval")))
    tone_manual_box.pack_start(@tone_interval_entry)
    tone_auto_radio = Gtk::RadioButton.new(_("auto"))
    tone_manual_radio = Gtk::RadioButton.new(tone_auto_radio,_("manual"))
    tone_auto_radio.signal_connect("toggled"){|w|
      tone_manual_box.set_sensitive(false)
      @tone_level = false
    }
    tone_manual_radio.signal_connect("toggled"){|w|
      tone_manual_box.set_sensitive(true)
      @tone_level = true
    }
    tone_int_box = Gtk::HBox.new
    tone_int_box.pack_start(tone_auto_radio)
    tone_int_box.pack_start(tone_manual_radio)
    tone_int_box.pack_start(tone_manual_box)
    tone_method_e_radio = Gtk::RadioButton.new(_("Use")+" uetone")
    tone_method_f_radio = Gtk::RadioButton.new(tone_method_e_radio,_("Use")+" uetonf ("+_("cellular")+" "+_("algorithm")+")")
    tone_method_c_radio = Gtk::RadioButton.new(tone_method_e_radio,_("Use")+" uetonc ("+_("cellular")+" "+_("tiling")+")")
    @tone_method = "uetone"
    tone_method_e_radio.signal_connect("toggled"){ @tone_method = "uetone" }
    tone_method_f_radio.signal_connect("toggled"){ @tone_method = "uetonf" }
    tone_method_c_radio.signal_connect("toggled"){ @tone_method = "uetonc" }
    tone_method_e_radio.set_active(true)
    tone_method_box = Gtk::HBox.new
    tone_method_box.pack_start(tone_method_e_radio)
    tone_method_box.pack_start(tone_method_f_radio)
    tone_method_box.pack_start(tone_method_c_radio)
    @tone_draw_button = Gtk::CheckButton.new(_("draw")).set_active(true)
    @tone_draw_button.signal_connect("toggled"){|w|
      tone_int_box.set_sensitive(w.active?)
      tone_method_box.set_sensitive(w.active?)
    }
    tone_table = Gtk::Table.new(2,3,false)
    tone_table.attach(Gtk::Label.new(_("Tone")),0,2,0,1)
    tone_table.attach(@tone_draw_button,1,2,1,2)
    tone_table.attach(Gtk::Label.new(_("Tone")+" "+_("interval")),0,1,2,3)
    tone_table.attach(tone_int_box,1,2,2,3)
    tone_table.attach(Gtk::Label.new(_("Method")),0,1,3,4)
    tone_table.attach(tone_method_box,1,2,3,4)
    level_box = Gtk::VBox.new
    level_box.pack_start(cont_table)
    level_box.pack_start(Gtk::HSeparator.new)
    level_box.pack_start(tone_table)
    cont_window.add(level_box.show_all)

# Vector Window
    @vector_scale_x_entry = Gtk::Entry.new
    @vector_scale_y_entry = Gtk::Entry.new
    scale_entry_box = Gtk::HBox.new.set_sensitive(false)
    scale_entry_box.pack_start(Gtk::Label.new("X"))
    scale_entry_box.pack_start(@vector_scale_x_entry)
    scale_entry_box.pack_start(Gtk::Label.new("Y"))
    scale_entry_box.pack_start(@vector_scale_y_entry)
    check = Gtk::CheckButton.new(_("manual"))
    check.signal_connect("toggled"){|w|
      scale_entry_box.set_sensitive(w.active?)
      @vector_factor = w.active?
    }
    scale_box = Gtk::HBox.new
    scale_box.pack_start(check)
    scale_box.pack_start(scale_entry_box)

    @vector_thinout_x_entry = Gtk::Entry.new
    @vector_thinout_y_entry = Gtk::Entry.new
    thinout_entry_box = Gtk::HBox.new.set_sensitive(false)
    thinout_entry_box.pack_start(Gtk::Label.new("X"))
    thinout_entry_box.pack_start(@vector_thinout_x_entry)
    thinout_entry_box.pack_start(Gtk::Label.new("Y"))
    thinout_entry_box.pack_start(@vector_thinout_y_entry)
    check = Gtk::CheckButton.new(_("enable"))
    check.signal_connect("toggled"){|w|
      thinout_entry_box.set_sensitive(w.active?)
      @vector_thinout = w.active?
    }
    thinout_box = Gtk::HBox.new
    thinout_box.pack_start(check)
    thinout_box.pack_start(thinout_entry_box)

    vector_table = Gtk::Table.new(2,2,false)
    vector_table.attach(Gtk::Label.new(_("Scale")),0,1,0,1)
    vector_table.attach(scale_box,1,2,0,1)
    vector_table.attach(Gtk::Label.new(_("Thin out")),0,1,1,2)
    vector_table.attach(thinout_box,1,2,1,2)
    vector_window.add(vector_table.show_all)
# Division Window
    @leng_div = Gtk::RadioButton.new(_("Lengthways"))
    @side_div = Gtk::RadioButton.new(@leng_div, _("Sideways"))
    @x_div = Gtk::Entry.new.set_text("1")
    @y_div = Gtk::Entry.new.set_text("1")
    val_table = Gtk::Table.new(2,3,false)
    val_table.attach(@leng_div,0,1,0,1)
    val_table.attach(@side_div,1,2,0,1)
    val_table.attach(Gtk::Label.new("X"),0,1,1,2)
    val_table.attach(@x_div,1,2,1,2)
    val_table.attach(Gtk::Label.new("Y"),0,1,2,3)
    val_table.attach(@y_div,1,2,2,3)
    val_table.set_sensitive(false)
    button = Gtk::CheckButton.new("divide")
    button.signal_connect("toggled"){|w|
      val_table.set_sensitive(w.active?)
    }
    div_box = Gtk::VBox.new
    div_box.pack_start(button)
    div_box.pack_start(val_table)
    div_window.add(div_box.show_all)

# Variable Combo
    @var_select = Var_select.new
    @var2_select = Var_select.new
    @axisx_select = Var_select.new
    @axisy_select = Var_select.new
    @var_select.signal{set_var}
    @var2_select.signal{set_var2}
    @axisx_select.signal{set_axisx}
    @axisy_select.signal{set_axisy}

# figure type item
    select_type = Proc.new{|type|
      type = type[0] if type.class == Array
      @fig_type = type
      set_type
    }

    items = [
      ["/"+_("Line"), Gtk::ItemFactory::ITEM,nil,nil,select_type,LINE],
      ["/"+_("Contour")+" & "+_("Tone"), Gtk::ItemFactory::ITEM,nil,nil,select_type,CONTOUR],
      ["/"+_("Map"), Gtk::ItemFactory::ITEM,nil,nil,select_type,MAP],
      ["/"+_("Vector"), Gtk::ItemFactory::ITEM,nil,nil,select_type,VECTOR]
    ]
    type_itemfact = Gtk::ItemFactory.new(Gtk::ItemFactory::TYPE_OPTION_MENU, "<type>", accel)
    type_itemfact.create_items(items)
    @typeomenu = type_itemfact.get_widget("<type>")
    @typeomenu.set_sensitive(false)
    @typemenu = Array.new
    @typemenu[LINE] = type_itemfact.get_item("/"+_("Line"))
    @typemenu[CONTOUR] = type_itemfact.get_item("/"+_("Contour")+" & "+_("Tone"))
    @typemenu[MAP] = type_itemfact.get_item("/"+_("Map"))
    @typemenu[VECTOR] = type_itemfact.get_item("/"+_("Vector"))

    select_func = Proc.new{|func|
      func = func[0] if func.class == Array
      set_func(func)
    }
    items = [ ["/"+_("Functions"), Gtk::ItemFactory::BRANCH ] ]
    Funcs1.each{|func|
      items.push( ["/"+_("Functions")+"/"+SFunc[func], Gtk::ItemFactory::ITEM, nil, nil, select_func, func ] )
    }
    type_itemfact.create_items(items)

# Draw button
    @crewindbutton = Gtk::CheckButton.new(_("new Window"))
    @drawbutton = Gtk::Button.new(_("draw")).set_sensitive(false)
    @drawbutton.signal_connect("clicked"){
      if @fig_type==FUNC
	exec_func
      else
	draw_x
      end
      }

# Select table
    table = Gtk::Table.new(2,7,false)
    table.attach(Gtk::Label.new(_("Variable")),0,1,0,1)
    table.attach(@var_select,1,2,0,1)
    table.attach(Gtk::Label.new(_("Variable")+"2"),0,1,1,2)
    table.attach(@var2_select,1,2,1,2)
    table.attach(Gtk::Label.new(_("Action")),0,1,2,3)
    table.attach(@typeomenu,1,2,2,3)
    table.attach(Gtk::Label.new(_("X-Axis")),0,1,3,4)
    table.attach(@axisx_select,1,2,3,4)
    table.attach(Gtk::Label.new(_("Y-Axis")),0,1,4,5)
    table.attach(@axisy_select,1,2,4,5)
    table.attach(@crewindbutton,0,1,6,7)
    table.attach(@drawbutton,1,2,6,7)

# Main Menu
    p_f_o = Proc.new{
      fs.set_title(_("Open File"))
      fs.complete("*.nc")
      fs.hide_fileop_buttons
      fs.set_select_multiple(true)
      @filecall = Proc.new{|filenames| file_open(filenames)}
      fs.show
    }
    p_f_o2 = Proc.new{ dfs.show } if defined?(DFileSelection)
    p_f_si = Proc.new{
      if !@draw.nil?
        fs.set_title(_("Save Image"))
        fs.complete("*.png")
        fs.show_fileop_buttons
        fs.set_select_multiple(false)
        @filecall = Proc.new{|filenames|
          filename = filenames[0]
          if !FileTest.exist?(filename)
            @draw.save_image(filename)
          else
            dialog = Gtk::Dialog.new
            dialog.set_modal(true)
            dialog.vbox.pack_start(Gtk::Label.new("Can "+filename+" overwrite ?"))
            ok_button=Gtk::Button.new(_("OK"))
            ok_button.signal_connect("clicked"){dialog.destroy; @draw.save_image(filename)}
            cancel_button=Gtk::Button.new(_("Cancel"))
            cancel_button.signal_connect("clicked"){dialog.destroy}
            dialog.action_area.pack_start(ok_button)
            dialog.action_area.pack_start(cancel_button)
            dialog.show_all
          end
        }
        fs.show
      end
    }
    p_f_sc = Proc.new{
      if !@draw.nil?
        fs.set_title(_("Save Code"))
        fs.complete("*.rb")
        fs.show_fileop_buttons
        fs.set_select_multiple(false)
        @filecall = proc{|filenames|
          filename = filenames[0]
          if !FileTest.exist?(filename)
            @draw.save_code(filename)
          else
            dialog = Gtk::Dialog.new
            dialog.set_modal(true)
            dialog.vbox.pack_start(Gtk::Label.new("Can "+filename+" overwrite ?"))
            ok_button=Gtk::Button.new(_("OK"))
            ok_button.signal_connect("clicked"){dialog.destroy; @draw.save_code(filename)}
            cancel_button=Gtk::Button.new(_("Cancel"))
            cancel_button.signal_connect("clicked"){dialog.destroy}
            dialog.action_area.pack_start(ok_button)
            dialog.action_area.pack_start(cancel_button)
            dialog.show_all
          end
        }
        fs.show
      end
    }
    p_f_sn = Proc.new{
      if !@draw.nil?
        fs.set_title(_("Save NetCDF"))
        fs.complete("*.nc")
        fs.show_fileop_buttons
        fs.set_select_multiple(false)
        @filecall = proc{|filenames|
          filename = filenames[0]
          if !FileTest.exist?(filename)
            file = NetCDF.create(filename)
            gphys = @draw_data.gphys
            gphys = gphys.copy if !(GPhys===gphys)
            GPhys::IO.write(file,gphys)
            file.close
          else
            dialog = Gtk::Dialog.new
            dialog.set_modal(true)
            dialog.vbox.pack_start(Gtk::Label.new("Can "+filename+" overwrite ?"))
            ok_button=Gtk::Button.new(_("OK"))
            ok_button.signal_connect("clicked"){
              dialog.destroy
              file = NetCDF.create(filename)
              gphys = @draw_data.gphys
              gphys = gphys.copy if !(GPhys===gphys)
              GPhys::IO.write(file,gphys)
              file.close
            }
            cancel_button=Gtk::Button.new(_("Cancel"))
            cancel_button.signal_connect("clicked"){dialog.destroy}
            dialog.action_area.pack_start(ok_button)
            dialog.action_area.pack_start(cancel_button)
            dialog.show_all
          end
        }
        fs.show
      end
    }
    p_f_q = Proc.new{finish}

    p_t = Proc.new{|data|
      if data.class==Array
	window,w = data
      else
	window = data
	w = window
      end
      if w.active? then window.show else window.hide end
    }

    p_h_a = Proc.new{
      dialog = Gtk::Dialog.new.set_title(_("About this program"))
      dialog.vbox.pack_start(Gtk::Label.new("\nGAVE version #{GAVE_VERSION}\n"))
      dialog.vbox.pack_start(Gtk::Label.new(_("This program is made by Seiya Nishizawa")))
      dialog.vbox.pack_start(Gtk::Label.new("seiya@kugi.kyoto-u.ac.jp\n"))
      ok_button=Gtk::Button.new(_("OK"))
      ok_button.signal_connect("clicked"){dialog.destroy}
      dialog.action_area.pack_start(ok_button)
      dialog.show_all
    }

    fileitem = [["/"+_("File")+"(_F)", Gtk::ItemFactory::BRANCH]]
    fileitem.push ["/"+_("File")+"(F)/"+_("Open")+"(_O)", Gtk::ItemFactory::STOCK_ITEM, "<control>O", Gtk::Stock::OPEN, p_f_o]
    fileitem.push ["/"+_("File")+"(F)/"+"Open DRuby", Gtk::ItemFactory::STOCK_ITEM, nil, Gtk::Stock::OPEN, p_f_o2] if defined?(DFileSelection)
    fileitem.push ["/"+_("File")+"(F)/"+_("Save Image")+"(_S)", Gtk::ItemFactory::STOCK_ITEM, "<control>S", Gtk::Stock::SAVE, p_f_si]
    fileitem.push ["/"+_("File")+"(F)/"+_("Save Code")+"(_C)", Gtk::ItemFactory::STOCK_ITEM, "<control>C", Gtk::Stock::SAVE, p_f_sc]
    fileitem.push ["/"+_("File")+"(F)/"+_("Save NetCDF")+"(_N)", Gtk::ItemFactory::STOCK_ITEM, "<control>N", Gtk::Stock::SAVE, p_f_sn]
    fileitem.push ["/"+_("File")+"(F)/"+_("Quit")+"(_Q)", Gtk::ItemFactory::STOCK_ITEM, "<control>Q", Gtk::Stock::QUIT, p_f_q]

    toolsitem = [["/"+_("Tools")+"(_T)", Gtk::ItemFactory::BRANCH]]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Variable")+"(_V)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, var_window]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Axis")+"(_A)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, axis_window]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Dimensions")+"(_D)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, @dims_window]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Attributes")+"(_T)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, attr_window]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Movie")+"(_O)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, movie_window]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Map")+"(_M)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, map_window]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Contour")+" & "+_("Tone")+"(_C)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, cont_window]
    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Vector")+"(_E)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, vector_window]
#    toolsitem.push ["/"+_("Tools")+"(T)/"+_("Division")+"(_I)", Gtk::ItemFactory::CHECK_ITEM, nil, nil, p_t, div_window]

    windowitem = [["/"+_("Windows")+"(_W)", Gtk::ItemFactory::BRANCH]]

    helpitem = [["/"+_("Help")+"(_H)", Gtk::ItemFactory::LAST_BRANCH]]
    helpitem.push ["/"+_("Help")+"(H)/"+_("About")+"(_A)", Gtk::ItemFactory::ITEM, nil, nil, p_h_a]

    items = fileitem + toolsitem + windowitem+helpitem
    @main_itemfact = Gtk::ItemFactory.new(Gtk::ItemFactory::TYPE_MENU_BAR, "<main>", accel)
    @main_itemfact.create_items(items)

    @save_image = @main_itemfact.get_item("/"+_("File")+"(F)/"+_("Save Image")+"(S)").set_sensitive(false)
    @save_code = @main_itemfact.get_item("/"+_("File")+"(F)/"+_("Save Code")+"(C)").set_sensitive(false)
    @save_netcdf = @main_itemfact.get_item("/"+_("File")+"(F)/"+_("Save NetCDF")+"(N)").set_sensitive(false)

    @check_var = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Variable")+"(V)")
    @check_axis = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Axis")+"(A)")
    @check_dims = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Dimensions")+"(D)")
    @check_attr = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Attributes")+"(T)")
    @check_movie = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Movie")+"(O)")
    @check_map = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Map")+"(M)")
    @check_level = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Contour")+" & "+_("Tone")+"(_C)")
    @check_vector = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Vector")+"(E)")
#    @check_div = @main_itemfact.get_item("/"+_("Tools")+"(T)/"+_("Division")+"(L)")


# main window
    totalbox = Gtk::VBox.new(false,0)
    totalbox.pack_start(@main_itemfact.get_widget("<main>"),false,true,0)
    totalbox.pack_start(table,false,true,0)
    main_window = Gtk::Window.new(TOPLEVEL).set_resizable(false)
    main_window.set_title("gave")
    main_window.add(totalbox)
    main_window.signal_connect("delete-event"){false}
    main_window.signal_connect("destroy"){finish}
    main_window.add_accel_group(accel)
    main_window.show_all

  end

  def showwindows
    @subwindows.each{|w| w.show}
  end


  def set_title(str); @title_entry.text=str; end
  def get_title;      @title_entry.text;     end
#  def set_missing(val); @miss_entry.text=val.to_s; end
#  def get_missing;      @miss_entry.text.to_f;     end
  def set_div(ary)
    ary[0]==0 ? @leng_div.active=true : @side_div.active=true
    @x_div.text = ary[1].to_s
    @y_div.text = ary[2].to_s
  end
  def get_div
    [@leng_div.active? ? 0 : 1, @x_div.text.to_i, @y_div.text.to_i]
  end

  def set_axis_x_log(tf); @logxbutton.active=tf; end
  def get_axis_x_log;     @logxbutton.active?;   end
  def set_axis_x_title(str); @x_title.text=str; end
  def get_axis_x_title;      @x_title.text;     end
  def set_axis_x_unit(str); @x_unit.text=str; end
  def get_axis_x_unit;      @x_unit.text; end
  def set_axis_x_min(val); @x_min.text=val.to_s; end
  def get_axis_x_min;      @x_min.text.to_f    ; end
  def set_axis_x_max(val); @x_max.text=val.to_s; end
  def get_axis_x_max;      @x_max.text.to_f    ; end
  def set_axis_y_log(tf); @logybutton.active=tf; end
  def get_axis_y_log;     @logybutton.active?;   end
  def set_axis_y_title(str); @y_title.text=str; end
  def get_axis_y_title;      @y_title.text;     end
  def set_axis_y_unit(str); @y_unit.text=str; end
  def get_axis_y_unit;      @y_unit.text; end
  def set_axis_y_min(val); @y_min.text=val.to_s; end
  def get_axis_y_min;      @y_min.text.to_f    ; end
  def set_axis_y_max(val); @y_max.text=val.to_s; end
  def get_axis_y_max;      @y_max.text.to_f    ; end

# OpenFile
  def add_attr_list(varray,name=nil)
    attr_list = List.new
    varray.att_names.each{|n|
      val = varray.get_att(n)
      if val.class==NArray then
        val = val.to_a.join(",")
      end
      attr_list.set_item(n, val)
    }
    attr_list.add_note(@attr_note,name ? name : varray.name)
  end
  def open_var(gphys, filenames, filetype)
    vn_o = gphys.name
    vn = vn_o
    if gphys.rank!=1 && gphys.axnames[0]!=vn then
      if @vars.has_key?(vn)
        i=2
        while @vars.has_key?(vn = vn_o+"(#{i})")
          i+=1
        end
      end
      @vars[vn] = gphys
      filenames = [filenames] if !(Array===filenames)
      @vars[vn].funcs = [[filenames, filetype, vn_o]]
      gphys.axnames.each{|an|
        val = gphys.coord(an).val
        i = nil
        an_o = an
        while true
          an = i ? an_o+"(#{i})" : an
          if @dims.has_key?(an) then
            if @dims[an].val == val
              an = nil
              break
            end
          else
            break
          end
          i ? i+=1 : i=2
        end
        if an
          @dims[an] = Select_value.new(val)
          add_attr_list(gphys.coord(an_o),an)
        end
      }
      add_attr_list(gphys.data)
    end
  end

  def file_open(filenames)
    if ! (filenames[0]=~/^druby:\/\//)
      filename = filenames.collect{|fn|
        fn.sub!(/^file:\/\//,"")
        if fn=~/^http:\/\//
          fn
        else
          File.expand_path(fn)
        end
      }
      begin
        file = NetCDF.open(filename[0],mode="r")
        filetype = "netcdf"
      rescue
        error_message1 = $!.to_s
        begin
          file = GrADS_Gridded.open(filename[0],mode="r")
          filetype = "grads"
        rescue
          error_message2 = $!.to_s
          dialog = Gtk::Dialog.new.set_title(_("Error Message"))
          dialog.set_modal(true)
          dialog.vbox.pack_start(Gtk::Label.new(filename[0]))
          dialog.vbox.pack_start(Gtk::Label.new(error_message1))
          dialog.vbox.pack_start(Gtk::Label.new(error_message2))
          dialog.vbox.pack_start(Gtk::Label.new("in opening File"))
          ok_button=Gtk::Button.new(_("OK"))
          ok_button.signal_connect("clicked"){dialog.destroy}
          dialog.action_area.pack_start(ok_button)
          dialog.show_all
          clear_all
          return
        end
      end

      if filename.length!=1
        vnames = file.var_names.sort
        divf = !filename[1..-1].each{|fn|
          begin
            f = {"netcdf"=>NetCDF,"grads"=>GrADS_Gridded}[filetype].open(fn,"r")
            vnames2 = f.var_names.sort
          ensure
            f.close
          end
          break if vnames2!=vnames
        }
      else
        filename = filename[0]
        divf = false
      end
      if divf
        file.close
        filename.each{|fn|
          begin
            f = {"netcdf"=>NetCDF,"grads"=>GrADS_Gridded}[filetype].open(fn,"r")
            f.var_names.each{|vn|
              gphys = GPhys::IO.open(fn,vn)
              open_var(gphys, fn, filetype)
            }
            attr_list = List.new
            f.each_att{|att|
              val = att.get
              if val.class==NArray then
                val = att.get.to_a.join(",")
              end
              attr_list.set_item(att.name, val)
            }
            attr_list.add_note(@attr_note, _("global")+" (#{File.basename(fn)})")
          ensure
            f.close
          end
        }
      else
        file.var_names.each{|vn|
          if file.var(vn).rank!=1 && file.var(vn).dim_names[0]!=vn
            gphys = GPhys::IO.open(filename,vn)
            open_var(gphys, filename, filetype)
          end
        }
        attr_list = List.new
        file.each_att{|att|
          val = att.get
          if val.class==NArray then
            val = att.get.to_a.join(",")
          end
          attr_list.set_item(att.name, val)
        }
        attr_list.add_note(@attr_note, _("global"))
        file.close
      end

    else
      ary = filenames[0].split("/")
      host = "druby://"+ary[2]
      path = ary[3..-1].join("/")
      raise "path is not given" if path==""
      tree = DRbObject.new(nil,host)
      gphys = tree.data(path)
      open_var(gphys, filenames, "druby")
    end

    clear_dim
    @dimtable = Gtk::Table.new(2, @dims.length, false)
    i=0
    @dims.keys.sort.each{|dim|
      @dimtable.attach(Gtk::Label.new(dim).set_size_request(30,20), 0, 1, i, i+1 )
      @dimtable.attach(@dims[dim].box, 1, 2, i, i+1 )
      i += 1
    }
    @dims_window.add(@dimtable.show_all)

    @var_select.set(@vars.keys.sort.reverse)
    @var_select.active
    set_var

  end

  def set_var
    vname = @var_select.get
    if !(vname==_("cannot select") ||vname=="") then
      @vname = vname
      gphys = @vars[@vname]
      title = gphys.name
      title += "("+gphys.units.to_s+")" if gphys.units.to_s!=""
      set_title(title)
      ax = gphys.axnames
      type = @draw_data && @draw_data.type
      if ax.length == 1 then
	@typeomenu.set_sensitive(false)
        axis = nil
        if type==LINE && ax.index(@x_name)
          axis = @x_name
        end
        clear_axisx
        @typeomenu.set_history(0)
	@typemenu[LINE].activate
        if axis
          @axisx_select.set_text(axis)
          set_axis_x_title( @draw_data.axis_x.title )
          set_axis_x_unit( @draw_data.axis_x.unit )
          set_axis_x_log( @draw_data.axis_x.log )
          set_axis_x_min( @draw_data.axis_x.min )
          set_axis_x_max( @draw_data.axis_x.max )
        end
      else
        axis = nil
        if type && type!=LINE && ax.index(@x_name) && ax.index(@y_name)
          axis = [@x_name,@y_name]
        end
        clear_axisx
	@axisx_select.set(ax)
        @axisx_select.set_text("")
	@typeomenu.set_sensitive(true)
        if axis
          @typeomenu.set_history(type)
          @typemenu[type].activate
          @axisx_select.set_text(axis[0])
          @axisy_select.set_text(axis[1])

          set_axis_x_title( @draw_data.axis_x.title )
          set_axis_x_unit( @draw_data.axis_x.unit )
          set_axis_x_log( @draw_data.axis_x.log )
          set_axis_x_min( @draw_data.axis_x.min )
          set_axis_x_max( @draw_data.axis_x.max )

          set_axis_y_title( @draw_data.axis_y.title )
          set_axis_y_unit( @draw_data.axis_y.unit )
          set_axis_y_log( @draw_data.axis_y.log )
          set_axis_y_min( @draw_data.axis_y.min )
          set_axis_y_max( @draw_data.axis_y.max )
        else
          @typeomenu.set_history(1)
          @typemenu[CONTOUR].activate
        end
      end
    end
  end

  def set_var2
    vname = @var2_select.get
    if !(vname==_("cannot select") ||vname=="") then
      @vname2 = vname
      gphys1 = @vars[@vname2]
      gphys2 = @vars[@vname]
      title = gphys1.name+","+gphys2.name
      set_title(title)
    end
  end

  def set_type
    @drawbutton.children[0].set_text(_("draw"))
    clear_axisx
    if @vname.nil? then return end
    x_name = @vars[@vname].axnames[0]
    if @fig_type == MAP
      @vars[@vname].axnames.each{|dim|
        if dim.downcase=~/^(lon|x)/ then
          x_name = dim
          break
        end
      }
    end
    if @fig_type == VECTOR
      vars2 = Array.new
      @vars.each_value{|v|
        next if v.name==@vname
        if v.shape == @vars[@vname].shape
          if v.rank.times{|i| break if v.coord(i).val != @vars[@vname].coord(i).val }
            vars2.push v.name
          end
        end
      }
      if vars2.length>0
        @var2_select.set(vars2)
        @var2_select.active
        set_var2
      else
        clear_axisx
        return
      end
    else
      clear_var2
    end
    @axisx_select.set_text(x_name)
    @axisx_select.active
  end

  def set_func(func)
    @fig_type = FUNC
    @func_type = func
    @drawbutton.children[0].set_text(SFunc[func])
    clear_axisx
    @axisx_select.set_text(@vars[@vname].axnames[0])
    @axisx_select.active
  end

  def set_axisx
    if @vname.nil? then return end
    clear_axisx
    name = @axisx_select.get
    if name==_("cannot select") || name=="" then
      clear_axisy
      return
    end
    @x_name = name
    set_axis_x_title(@x_name)
    x = @vars[@vname].coord(@x_name)
    x.att_names.each{|key|
      if key=~/unit/ then set_axis_x_unit(x.get_att(key)) end
    }
    @x_frame.set_sensitive(true)
    if @fig_type == FUNC then
      clear_axisy
      func_ok
      return
    elsif @fig_type == LINE
      clear_axisy({"axisy_hide"=>true})
      draw_ok
      return
    else
      clear_axisy
      ay = @vars[@vname].axnames
      ay.delete(@x_name)
      @axisy_select.set(ay)
      y_name = ay[0]
      if @fig_type == MAP then
        ay.each{|dim|
          if dim.downcase=~/^(lat|y)/ then
            y_name = dim
            flag = false
            break
          end
        }
      end
      @axisy_select.set_text(y_name)
      @axisy_select.active
      set_axisy
      return
    end
  end
  def set_axisy
    if @vname.nil? then return end
    clear_axisy
    name = @axisy_select.get
    if name!=_("cannot select") && name!="" then
      @y_name = name
      set_axis_y_title(@y_name)
      y = @vars[@vname].coord(@y_name)
      y.att_names.each{|key|
	if key=~/unit/ then set_axis_y_unit(y.get_att(key)) end
      }
      @y_frame.set_sensitive(true)
      draw_ok
    end
  end

  def func_ok
    clear_draw
    @drawbutton.set_sensitive(true)
  end
  def draw_ok
    clear_draw
    dims = @vars[@vname].axnames
    dims.delete(@x_name)
    dims.delete(@y_name)
    if dims.length!=0 then
      @movie_combo.set_popdown_strings(dims)
      @movie_box.set_sensitive(true)
      dims.each{|dn| @dims[dn].active }
    end
    @drawbutton.set_sensitive(true)
    if @autodraw
      @autodraw=false
      @drawbutton.clicked
    end
  end

  def clear_all(option={})
    clear_var(option)
  end
  def clear_var(option={})
    hide = option.delete("var_hide")
    if hide
      option["var2_hide"]=true
      option["axisx_hide"]=true
      option["axisy_hide"]=true
    end
    clear_dim
    clear_var2(option)
    clear_axisx(option)
    if @vname.nil? then return end
    @var_select.not_active if hide
    @vname = nil
  end
  def clear_var2(option={})
    hide = option.delete("var2_hide")
    if @vname2.nil? then return end
    @var2_select.not_active if hide
    @vname2 = nil
  end
  def clear_dim(option={})
    if !@dimtable.nil?
      @dimtable.hide
      @dims_window.remove(@dimtable)
      @dimtable.each{|w| @dimtable.remove(w)}
    end
  end
  def clear_axisx(option={})
    hide = option.delete("axisx_hide")
    if hide
      option["axisy_hide"]=true
    end
    clear_axisy(option)
    @axisx_select.not_active if hide
    @x_name = nil
    @x_frame.set_sensitive(false)
    set_axis_x_log(false)
    set_axis_x_title("")
    set_axis_x_unit("")
    set_axis_x_min(nil)
    set_axis_x_max(nil)
  end
  def clear_axisy(option={})
    hide = option.delete("axisy_hide")
    clear_draw(option)
    @axisy_select.not_active if hide
    @y_name = nil
    set_axis_y_log(false)
    set_axis_y_title("")
    set_axis_y_unit("")
    set_axis_y_min(nil)
    set_axis_y_max(nil)
  end
  def clear_draw(option={})
    @drawbutton.set_sensitive(false)
    @dims.each_value{|dim| dim.not_active}
    @movie_box.set_sensitive(false)
    @movie_combo.entry.set_text("-")
    set_div([false,1,1])
  end

  def exec_func
    gphys = @vars[@vname]
    ofuncs = gphys.funcs
    min = get_axis_x_min
    max = get_axis_x_max
    min = gphys.coord(@x_name)[0].val[0] if !min
    max = gphys.coord(@x_name)[-1].val[0] if !max
    index = Array.new(gphys.rank)
    ix = gphys.axnames.index(@x_name)
    gphys.rank.times{|i|
      if i==ix then index[i] = min..max else index[i] = true end
    }
    func = [@func_type,ix,index]
    it = 0
    for var in @vars
      funcs = var[1].funcs
      if funcs.length==1 || funcs[0..-2]!=ofuncs || funcs[-1][0..1]!=func[0..1] then
	next
      elsif funcs[-1]==func
	it = false
	break
      elsif
	it += 1
      end
    end
    if it then
      if it>0 then add = "-#{it}" else add = "" end
      vn2 = "#{@vname} (#{@x_name} #{@func_type}#{add})"
      gphys = gphys.cut(*index)
      @vars[vn2] = gphys.send(@func_type,ix)
      @vars[vn2].funcs=(ofuncs.push([@func_type,ix,index]))
      @vars[vn2].name = vn2
      @var_select.not_active
      @var_select.set(@vars.keys.sort.reverse)
      @var_select.active
    end
    clear_var({"var_hide"=>true})
    set_var
  end

  def make_draw_data
    draw_data = Draw_data.new

    gphys = @vars[@vname]
    dims = gphys.axnames
    index = Array.new(dims.length)
    dims.each_with_index{|dim,i|
      if dim==@x_name||dim==@y_name then
        if @fig_type==VECTOR && @vector_thinout
          if dim==@x_name
            step = @vector_thinout_x_entry.text.to_i
          elsif dim==@y_name
            step = @vector_thinout_y_entry.text.to_i
          end
          len = (gphys.axis(dim).length/step).floor
          index[i] = NArray.sint(len).indgen(0,step)
        else
          index[i] = 0..-1
        end
      else
	index[i] = @dims[dim].index
      end
    }
    gphys = gphys[*index]
    if @fig_type==VECTOR
      gphys2 = @vars[@vname2]
      gphys2 = gphys2[*index]
    else
      gphys2 = nil
    end
    draw_data.type = @fig_type
    dims = gphys.axnames
    if @fig_type!=LINE
      if dims.index(@x_name)>dims.index(@y_name) then
        draw_data.transpose = true
      else
        draw_data.transpose = false
      end
    end

    draw_data.axis_x.title = get_axis_x_title
    unit = get_axis_x_unit
    if unit != ""
      draw_data.axis_x.unit = unit
      if unit != gphys.coord(0).units.to_s
        coord = gphys.coord(0)
        gphys.axis(0).set_pos( coord.units.convert2(coord,Units.new(unit)) )
      end
    end
    draw_data.axis_y.title = get_axis_y_title
    unit = get_axis_y_unit
    if unit != ""
      draw_data.axis_y.unit = unit
      if @fig_type==CONTOUR || @fig_type==VECTOR
        if unit != gphys.coord(1).units.to_s
          coord = gphys.coord(1)
          gphys.axis(1).set_pos( coord.units.convert2(coord,Units.new(unit)) )
        end
      end
    end

    x = gphys.coord(@x_name).val
    min = get_axis_x_min
    max = get_axis_x_max
    min = x[0] if !min
    max = x[-1] if !max
    draw_data.axis_x.min = min
    draw_data.axis_x.max = max

    min = get_axis_y_min
    max = get_axis_y_max
    if @fig_type==LINE
      min = gphys.data.min if !min
      min = min.val if !(Numeric===min)
      max = gphys.data.max if !max
      max = max.val if !(Numeric===max)
    elsif @fig_type==MAP
      lat = @pole_lat.text.to_f
      y = gphys.coord(@y_name).val
      if (!min)&&(!max)
        min,max = [y[0],y[-1]]
        if min*max < 0
          if min.abs<max.abs
            min = 0
            lat = max>0 ? 90 : -90 unless lat
          else
            max = 0
            lat = min>0 ? 90 : -90 unless lat
          end
        else
          lat = max > 0 ? 90 : -90 unless lat
        end
      elsif (!min)&&max
        min = y[0]
        lat = max>0 ? 90 : -90 unless lat
      elsif min&&(!max)
        max = y[-1]
        lat = min>0 ? 90 : -90 unless lat
      else
        if !lat
          if max.abs>min.abs
            lat = max>0 ? 90 : -90
          else
            lat = min>0 ? 90 : -90
          end
        end
      end
      lon = @pole_lon.text.to_f
      rot = @pole_rot.text.to_f
      lon = 0 unless lon
      rot = 0 unless rot
      draw_data.map_pole = [lon,lat,rot]
    else
      y = gphys.coord(@y_name).val
      min = y[0] if !min
      max = y[-1] if !max
    end
    draw_data.axis_y.min = min
    draw_data.axis_y.max = max

    log = get_axis_x_log
    if (min(draw_data.axis_x.min,draw_data.axis_x.max)<=0) && log then
      dialog = Gtk::Dialog.new.set_title(_("Error Message"))
      dialog.set_modal(true)
      dialog.vbox.pack_start(Gtk::Label.new(_("X-Axis")+" "+_("has negative value for log scale")))
      ok_button=Gtk::Button.new(_("OK"))
      ok_button.signal_connect("clicked"){dialog.destroy}
      dialog.action_area.pack_start(ok_button)
      dialog.show_all
      return
    end
    draw_data.axis_x.log = log

    log = get_axis_y_log
    if (min(draw_data.axis_y.min,draw_data.axis_y.max)<=0) and log then
      dialog = Gtk::Dialog.new.set_title(_("Error Message"))
      dialog.set_modal(true)
      dialog.vbox.pack_start(Gtk::Label.new(_("Y-Axis")+" "+_("has negative value for log scale")))
      ok_button=Gtk::Button.new(_("OK"))
      ok_button.signal_connect("clicked"){dialog.destroy}
      dialog.action_area.pack_start(ok_button)
      dialog.show_all
      return
    end
    draw_data.axis_y.log = log

    if @fig_type==LINE
      x = draw_data.axis_x
      xmin = x.min
      xmax = x.max
      x = gphys.coord(0).val
      if (x[-1]-x[0])/(xmax-xmin) < 0
        xmin,xmax = [xmax,xmin]
      end
      gphys = gphys.cut(xmin..xmax)
    else
      x = draw_data.axis_x
      y = draw_data.axis_y
      if draw_data.transpose
        x,y = [y,x]
      end
      xmin = x.min
      xmax = x.max
      ymin = y.min
      ymax = y.max
      x = gphys.coord(0).val
      y = gphys.coord(1).val
      if (x[-1]-x[0])/(xmax-xmin) < 0
        xmin,xmax = [xmax,xmin]
      end
      if (x[-1]-x[0])/(xmax-xmin) < 0
        xmin,xmax = [xmax,xmin]
      end
      gphys = gphys.cut(xmin..xmax, ymin..ymax)
    end

    

#    draw_data.missing_value = get_missing
    draw_data.title = get_title
    if @fig_type==CONTOUR || @fig_type==MAP
      if @cont_draw_button.active?
        draw_data.cont = true
        if @cont_level
          draw_data.cont_i = [@cont_min_entry.text.to_f,@cont_interval_entry.text.to_f]
        else
          draw_data.cont_i = nil
        end
      else
        draw_data.cont = nil
      end
      if @tone_draw_button.active?
        draw_data.tone = @tone_method
        if @tone_level
          draw_data.tone_i = [@tone_min_entry.text.to_f,@tone_interval_entry.text.to_f]
        else
          draw_data.tone_i = nil
        end
      else
        draw_data.tone = nil
      end
    end

    if @fig_type==MAP then
      draw_data.map_type = @map_type.index(@map_combo.entry.text)+30
      draw_data.map_draw = @map_check.active?
    else
      draw_data.map_type = nil
    end

    if @fig_type==VECTOR && @vector_factor
      draw_data.vector = [@vector_x_entry.text.to_f,@vector_y_entry.text.to_f]
    else
      draw_data.vector = nil
    end

    draw_data.gphys = gphys
    draw_data.gphys2 = gphys2

    return draw_data
  end

  def add_window
    if defined?(@nwindows)
      @nwindows += 1
      type = "/"+_("Windows")+"(W)/1"
    else
      @dwindows = Array.new
      @nwindows = 1
      type = Gtk::ItemFactory::RADIO_ITEM
    end
    draw = Draw.new(@nwindows)
    @dwindows.push draw
    windowitem = [["/"+_("Windows")+"(_W)", Gtk::ItemFactory::BRANCH]]
    path = "/"+_("Windows")+"(W)/#{@nwindows}"
    @main_itemfact.create_item(path, type, nil, nil, @nwindows){|n, wid|
      if wid.active?
        @draw = @dwindows[n-1]
        @draw.show
      end
    }
    @main_itemfact.get_item(path).active = true
    draw
  end

  def draw_x
    @draw_data = make_draw_data
    @save_image.set_sensitive(true)
    @save_code.set_sensitive(true)
    @save_netcdf.set_sensitive(true)
    @draw = add_window if @draw.nil?|@crewindbutton.active?
    @draw.draw_x(@draw_data)
  end


  def draw_next
    dim = @movie_combo.entry.text
    return if dim=="-"
    @dims[dim].next 
    draw_x
  end

# start
  def start
    Gtk.main
  end

# quit
  def file_close
    clear_var
    @vars.clear
    @dims.clear
  end
  def finish
    file_close
    Gtk.main_quit
  end

end



argv = ARGV

$main = GAVE.new

$main.autodraw = argv.delete("--draw") || argv.delete("-d")
$main.autodraw = argv.delete("-autodraw") || $main.autodraw # Obsolute

$main.showwindows if argv.delete("--show_windows") || argv.delete("-s")

badoptions = ""
argv.each{|str|
  if str[0..0] == "-"
    badoptions += str+","
  end
}
raise "No such options: #{badoptions.chop!}" if badoptions != ""

begin
  $main.file_open(argv) if argv.length!=0
  argv=[]

  $main.start
rescue
  dialog = Gtk::Dialog.new.set_title(_("Error Message"))
  dialog.set_modal(true)
  p $!.exception.message
  str = "\n"+$!.message+"\n"
  str += $!.backtrace.join("\n")+"\n\n"
  label = Gtk::Label.new(str)
  label.selectable=true
  label.justify=Gtk::Justification::CENTER
  dialog.vbox.pack_start(label)
  str = _("If this error have come from bug of this program, please report to")
  str += "\n<seiya@kugi.kyoto-u.ac.jp>\n"
  label = Gtk::Label.new(str)
  label.selectable=true
  label.justify=Gtk::Justification::CENTER
  label.wrap=true
  dialog.vbox.pack_start(label)
  ok_button=Gtk::Button.new(_("OK"))
  ok_button.signal_connect("clicked"){dialog.destroy}
  dialog.action_area.pack_start(ok_button)
  dialog.signal_connect("destroy"){Gtk.main_quit}
  dialog.show_all
  Gtk.main
  $main.clear_var({"var_hide"=>true})
  $main.set_var
  argv = []
  retry
end
