#!/usr/bin/env ruby

require "gtk"
require "numru/gphys"
require "numru/netcdf"
require "numru/gave/draw"

begin
  require "gettext"
  include GetText
  gettext_path = "/usr/share/locale"
  bindtextdomain("gave",gettext_path)
rescue LoadError
  def _(str); str; end
end

include NumRu

class Select_value
  attr_reader :index, :box
  def initialize(var)
    height=20
    @max = var.length-1
    @index = 0
    entry = Gtk::Entry.new
    entry.set_usize(50,height)
    entry.set_editable(false)
    entry.set_text(var[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(var[@index].to_s)
    }
    @scale = Gtk::HScale::new(@adjustment)
    @scale.set_usize(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
end

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


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

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


class GAVE

  def s2f(str)
    if str=="" then
      false
    else
      str.to_f
    end
  end
  def min(x,y)
    x<y ? x : y
  end

  def initialize

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

    accel = Gtk::AccelGroup.new

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

# sub windows
    var_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL).set_title(_("Variable"))
    axis_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL).set_title(_("Axis"))
    @dims_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL).set_title(_("Dimensions"))
    attr_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL).set_title(_("Attributes"))
    movie_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL).set_title(_("Movie"))
    map_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL).set_title(_("Map"))
    level_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL).set_title(_("Levels for Contour and Tone"))
    var_window.signal_connect("delete_event"){|w,e|
      w.hide
      @check_var.set_active(false)
    }
    axis_window.signal_connect("delete_event"){|w,e|
      w.hide
      @check_axis.set_active(false)
    }
    @dims_window.signal_connect("delete_event"){|w,e|
      w.hide
      @check_dims.set_active(false)
    }
    attr_window.signal_connect("delete_event"){|w,e|
      w.hide
      @check_attr.set_active(false)
    }
    movie_window.signal_connect("delete_event"){|w,e|
      w.hide
      @check_movie.set_active(false)
    }
    map_window.signal_connect("delete_event"){|w,e|
      w.hide
      @check_map.set_active(false)
    }
    level_window.signal_connect("delete_event"){|w,e|
      w.hide
      @check_level.set_active(false)
    }

# 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"))
    @logxbutton.signal_connect("clicked"){|w| @draw_data.axis_x.log = w.active?}
    @x_title = Gtk::Entry.new
    @x_title.signal_connect("activate"){|w| @draw_data.axis_x.title = w.get_text}
    @x_unit = Gtk::Entry.new
    @x_unit.signal_connect("activate"){|w| @draw_data.axis_x.unit = w.get_text}
    @x_min = Gtk::Entry.new
    @x_min.signal_connect("activate"){|w|
      str = w.get_text
      if str=="" then
	@draw_data.axis_x.min = false
      else
	@draw_data.axis_x.min = str.to_f
      end
    }
    @x_max = Gtk::Entry.new
    @x_max.signal_connect("activate"){|w|
      str = w.get_text
      if str=="" then
	@draw_data.axis_x.max = false
      else
	@draw_data.axis_x.max = str.to_f
      end
    }
    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"))
    @logybutton.signal_connect("clicked"){|w| @draw_data.axis_y.log = w.active?}
    @y_title = Gtk::Entry.new
    @y_title.signal_connect("activate"){|w| @draw_data.axis_y.title = w.get_text}
    @y_unit = Gtk::Entry.new
    @y_unit.signal_connect("activate"){|w| @draw_data.axis_y.unit = w.get_text}
    @y_min = Gtk::Entry.new
    @y_min.signal_connect("activate"){|w|
      str = w.get_text
      if str=="" then
	@draw_data.axis_y.min = false
      else
	@draw_data.axis_y.min = str.to_f
      end
    }
    @y_max = Gtk::Entry.new
    @y_max.signal_connect("activate"){|w|
      str = w.get_text
      if str=="" then
	@draw_data.axis_y.max = false
      else
	@draw_data.axis_y.max = str.to_f
      end
    }
    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)
    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
    pix, mask = Gdk::Pixmap.create_from_xpm_d(movie_window.window, nil, start_xpm) 
    start_pixmap =  Gtk::Pixmap.new(pix, mask)
    pix, mask = Gdk::Pixmap.create_from_xpm_d(movie_window.window, nil, stop_xpm) 
    stop_pixmap =  Gtk::Pixmap.new(pix, mask)
    pix, mask = Gdk::Pixmap.create_from_xpm_d(movie_window.window, nil, rec_xpm) 
    rec_pixmap =  Gtk::Pixmap.new(pix, mask)
    start_button = Gtk::ToggleButton.new
    start_button.add(Gtk::HBox.new.pack_start(start_pixmap))
    stop_button = Gtk::Button.new
    stop_button.add(Gtk::HBox.new.pack_start(stop_pixmap))
    rec_button = Gtk::ToggleButton.new
    rec_button.add(Gtk::HBox.new.pack_start(rec_pixmap))
    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+".ppm")
	      @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_usize(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_usize(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
    @maps =  [_("ORTHOGRAPHIC"),_("POLAR STEREO"),_("AZIMUTHAL"),_("AZIMUTHAL EQ. AREA")]
    @map_combo = Gtk::Combo.new
    @map_combo.entry.set_editable(false)
    @map_combo.set_popdown_strings(@maps)
    box = Gtk::VBox.new(false,0)
    box.pack_start(@map_combo)
    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
    }
    box = Gtk::HBox.new
    box.pack_start(cont_auto_radio)
    box.pack_start(cont_manual_radio)
    box.pack_start(cont_manual_box)
    cont_box = Gtk::VBox.new
    cont_box.pack_start(Gtk::Label.new(_("Contour")))
    cont_box.pack_start(box)
    @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
    }
    box = Gtk::HBox.new
    box.pack_start(tone_auto_radio)
    box.pack_start(tone_manual_radio)
    box.pack_start(tone_manual_box)
    tone_box = Gtk::VBox.new
    tone_box.pack_start(Gtk::Label.new(_("Tone")))
    tone_box.pack_start(box)
    level_box = Gtk::VBox.new
    level_box.pack_start(cont_box)
    level_box.pack_start(Gtk::HSeparator.new)
    level_box.pack_start(tone_box)
    level_window.add(level_box.show_all)

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

# figure type item
    type_itemfact = Gtk::ItemFactory.new(Gtk::ItemFactory::TYPE_OPTION_MENU, "<type>", accel)
    type_itemfact.create_item("/"+_("Line"), nil, Gtk::ItemFactory::ITEM){
      @draw_data.type = LINE
      set_type(@draw_data.gphys.axnames[0])
    }
    type_itemfact.create_item("/"+_("Contour"), nil, Gtk::ItemFactory::ITEM){
      @draw_data.type = CONTOUR
      set_type(@draw_data.gphys.axnames[0])
    }
    type_itemfact.create_item("/"+_("Map"), nil, Gtk::ItemFactory::ITEM){
      @draw_data.type = MAP
      tmp = true
      @vars[@draw_data.gphys.name].axnames.each{|dim|
	if dim.downcase=~/^(lon|x)/ then
	  set_type(dim)
	  tmp = false
	  break
	end
      }
      set_type(@draw_data.gphys.axnames[0]) if tmp
    }
    @typeomenu = type_itemfact.get_widget("<type>")
    @linemenu = type_itemfact.get_item("/"+_("Line"))
    @contourmenu = type_itemfact.get_item("/"+_("Contour"))
    type_itemfact.create_item("/"+_("Functions"),nil,Gtk::ItemFactory::BRANCH)
    Funcs1.each{|func|
      type_itemfact.create_item("/"+_("Functions")+"/"+SFunc[func],nil,Gtk::ItemFactory::ITEM){ set_func(func) }
    }

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

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

# Main Menu
    main_itemfact = Gtk::ItemFactory.new(Gtk::ItemFactory::TYPE_MENU_BAR, "<main>", accel)
    main_itemfact.create_item("/"+_("File")+"(_F)", nil, Gtk::ItemFactory::BRANCH)
    main_itemfact.create_item("/"+_("File")+"(_F)/"+_("Open")+"(_O)", nil, Gtk::ItemFactory::ITEM){
      fs.set_title(_("Open File"))
      @filecall = proc{|filename| file_open(filename)}
      fs.show
    }
    main_itemfact.create_item("/"+_("File")+"(_F)/"+_("Save Image")+"(_S)", "<control>S", Gtk::ItemFactory::ITEM){
      if !@draw.nil? then
	fs.set_title(_("Save Image"))
	@filecall = proc{|filename|
	  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
    }
    main_itemfact.create_item("/"+_("File")+"(_F)/"+_("Save Code")+"(_C)", "<control>C", Gtk::ItemFactory::ITEM){
      if !@draw.nil? then
	fs.set_title(_("Save Code"))
	@filecall = proc{|filename|
	  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
    }
    #main_itemfact.create_item("/File(_F)/Close(_C)", "<control>C", Gtk::ItemFactory::ITEM){file_close}
    main_itemfact.create_item("/"+_("File")+"(_F)/"+_("Quit")+"(_Q)", "<control>Q", Gtk::ItemFactory::ITEM){finish}
    @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)


    main_itemfact.create_item("/"+_("Tools")+"(_T)", nil, Gtk::ItemFactory::BRANCH)
    main_itemfact.create_item("/"+_("Tools")+"(_T)/"+_("Variable")+"(_V)", nil, Gtk::ItemFactory::CHECK_ITEM){|w|
      if w.active? then var_window.show else var_window.hide end
    }
    main_itemfact.create_item("/"+_("Tools")+"(_T)/"+_("Axis")+"(_A)", nil, Gtk::ItemFactory::CHECK_ITEM){|w|
      if w.active? then axis_window.show else axis_window.hide end
    }
    main_itemfact.create_item("/"+_("Tools")+"(_T)/"+_("Dimensions")+"(_D)", nil, Gtk::ItemFactory::CHECK_ITEM){|w|
      if w.active? then @dims_window.show else @dims_window.hide end
    }
    main_itemfact.create_item("/"+_("Tools")+"(_T)/"+_("Attributes")+"(_T)", nil, Gtk::ItemFactory::CHECK_ITEM){|w|
      if w.active? then attr_window.show else attr_window.hide end
    }
    main_itemfact.create_item("/"+_("Tools")+"(_T)/"+_("Movie")+"(_O)", nil, Gtk::ItemFactory::CHECK_ITEM){|w|
      if w.active? then movie_window.show else movie_window.hide end
    }
    main_itemfact.create_item("/"+_("Tools")+"(_T)/"+_("Map")+"(_M)", nil, Gtk::ItemFactory::CHECK_ITEM){|w|
      if w.active? then map_window.show else map_window.hide end
    }
    main_itemfact.create_item("/"+_("Tools")+"(_T)/"+_("Level")+"(_L)", nil, Gtk::ItemFactory::CHECK_ITEM){|w|
      if w.active? then level_window.show else level_window.hide end
    }
    @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)/"+_("Level")+"(L)")

    main_itemfact.create_item("/"+_("Help")+"(_H)", nil, Gtk::ItemFactory::LAST_BRANCH)
    main_itemfact.create_item("/"+_("Help")+"(_H)/"+_("About")+"(_A)", nil, Gtk::ItemFactory::ITEM){
      dialog = Gtk::Dialog.new.set_title(_("About this program"))
      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"))
      ok_button=Gtk::Button.new(_("OK"))
      ok_button.signal_connect("clicked"){dialog.destroy}
      dialog.action_area.pack_start(ok_button)
      dialog.show_all
    }

# 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)
    totalbox.signal_connect("destroy"){finish}
    main_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
    accel.attach(main_window)
    main_window.set_title("gave")
    main_window.add(totalbox)
    main_window.signal_connect("delete_event"){finish}
    main_window.signal_connect("destroy"){finish}
    main_window.show_all

  end


# OpenFile
  def file_open(filename)
    filename = File.expand_path(filename)
    printf( _("open %s\n"),filename )
    begin
      @file = NetCDF.open(filename,mode="r")
    rescue
      dialog = Gtk::Dialog.new.set_title(_("Error Message"))
      dialog.set_modal(true)
      dialog.vbox.pack_start(Gtk::Label.new(filename))
      dialog.vbox.pack_start(Gtk::Label.new($!))
      ok_button=Gtk::Button.new(_("OK"))
      ok_button.signal_connect("clicked"){dialog.destroy}
      dialog.action_area.pack_start(ok_button)
      dialog.show_all
    else
      @draw_data = Draw_data.new
      @draw_data.filename = filename
      
      clear_var
      @vars.clear
      @dims.clear
      @dimtable.hide if !@dimtable.nil?

      @file.var_names.each_index{|i|
	vn = @file.var_names[i]
	var = @file.var(vn)
	dims = var.dim_names
	if (dims.length==1) && (dims[0]==vn) && (! @dims.has_key?(vn)) then
	  @dims[vn] = Select_value.new(var.get)
	elsif ! @vars.has_key?(vn)
	  @vars[vn] = GPhys::NetCDF_IO.open(@file,vn)
	end
	clist = Gtk::CList.new([_("name"),_("value")])
	clist.set_usize(300, 200)
	clist.set_column_width(0,100)
	var.each_att{|att|
	  val = att.get
	  if val.type==NArray then
	    val = att.get.to_a.join(",")
	  end
	  clist.append([att.name,val])
	}
	@attr_note.append_page_menu(clist.show,Gtk::Label.new(vn),Gtk::Label.new(vn))
      }
      clist = Gtk::CList.new([_("name"),_("value")])
      clist.set_usize(300, 200)
      clist.set_column_width(0,100)
      @file.each_att{|att|
	val = att.get
	if val.type==NArray then
	  val = att.get.to_a.join(",")
	end
	clist.append([att.name,val])
      }
      @attr_note.append_page_menu(clist.show,Gtk::Label.new(_("global")),Gtk::Label.new("global"))

      @dimtable = Gtk::Table.new(2, @dims.length, false)
      i=0
      @dims.each_key{|dim|
	@dimtable.attach(Gtk::Label.new(dim).set_usize(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

  end

  def set_var
    vname = @var_select.get
    if !(vname =~ /^select/) then
      printf( _("variable")+_(" name is %s\n"),vname )
      gphys = @vars[vname]
      gphys.data.att_names.each{|key|
	value = gphys.data.get_att(key)
	if key=~/miss/ then @miss_entry.set_text(value[0].to_s) end
	if key=~/name/ then @title_entry.set_text(value) end
	if key=~/unit/ then
	  tmp=@title_entry.get_text+"("+value+")"
	  @title_entry.set_text(tmp)
	end
      }
      @draw_data.gphys = gphys
      ax = gphys.axnames
      clear_axisx
      if ax.length == 1 then
	@typeomenu.set_sensitive(false)
	@typeomenu.set_history(0)
	@linemenu.activate
      else
	@typeomenu.set_history(1)
	@contourmenu.activate
	@axisx_select.set(ax)
	@axisx_select.active
	@typeomenu.set_sensitive(true)
      end
    end
  end

  def set_type(x_name)
    clear_axisx
    @drawbutton.children[0].set_text(_("draw"))
    @axisx_select.set_text(x_name)
    set_axisx
    @axisx_select.active
  end

  def set_func(func)
    @draw_data.type = FUNC
    @func_type = func
    @drawbutton.children[0].set_text(SFunc[func])
    clear_axisx
    @axisx_select.set_text(@draw_data.gphys.axnames[0])
    set_axisx
    @axisx_select.active
  end

  def set_axisx
    @x_name = @axisx_select.get
    if @x_name =~ /^select/ then
      clear_axisy
      @draw_data.axis_x.clear
    else
      printf( _("X-Axis")+_(" name is %s\n"),@x_name )
      @draw_data.axis_x.title = @x_name
      @x_title.set_text(@x_name)
      x = @draw_data.gphys.coord(@x_name)
      x.att_names.each{|key|
	if key=~/unit/ then @x_unit.set_text(x.get_att(key)) end
      }
      clear_axisy
      ay = @vars[@draw_data.gphys.name].axnames.dup
      ay.delete(@x_name)
      if @draw_data.type == FUNC then
	func_ok
      elsif @draw_data.type == LINE
	draw_ok
      else
	@axisy_select.set(ay)
	if @draw_data.type == MAP then
	  ay.each{|dim|
	    if dim.downcase=~/^(lat|y)/ then
	      @axisy_select.set_text(dim)
	      break
	    end
	  }
	end
	@axisy_select.active
	set_axisy
      end
    end
  end
  def set_axisy
    @y_name = @axisy_select.get
    if @y_name =~ /^select/ then
      @draw_data.axis_y.clear
    else
      printf( _("Y-Axis")+_(" name is %s\n"),@y_name )
      @draw_data.axis_y.title = @y_name
      @y_title.set_text(@y_name)
      y = @draw_data.gphys.coord(@y_name)
      y.att_names.each{|key|
	if key=~/unit/ then @y_unit.set_text(y.get_att(key)) end
      }
      draw_ok
    end
  end

  def func_ok
    clear_draw
    @drawbutton.set_sensitive(true)
  end

  def draw_ok
    clear_draw
    dims = @vars[@draw_data.gphys.name].axnames.dup
    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)
  end

  def clear_var
    @draw_data.clear_var
    @var_select.not_active
  end
  def clear_axisx
    @x_name = nil
    @draw_data.axis_x.clear
    clear_axisy
    @axisx_select.not_active
    @logxbutton.set_active(false)
    @x_title.set_text("")
  end
  def clear_axisy
    @y_name = nil
    @draw_data.axis_y.clear
    clear_draw
    @axisy_select.not_active
    @logybutton.set_active(false)
    @y_title.set_text("")
  end
  def clear_draw
    @drawbutton.set_sensitive(false)
    @dims.each_value{|dim| dim.not_active}
    @movie_box.set_sensitive(false)
    @movie_combo.entry.set_text("-")
  end

  def exec_func
    vn = @draw_data.gphys.name
    vn2 = "#{vn} (#{@x_name} #{@func_type})"
    if !@vars.has_key?(vn2)
      gphys = @vars[vn]
      index = gphys.axnames.index(@x_name)
      eval ("@vars[vn2] = gphys.#{@func_type}(index)")
      @draw_data.funcs.push(vn) if @draw_data.funcs.length==0
      @draw_data.funcs.push([@func_type,index])
      @vars[vn2].name = vn2
      @var_select.not_active
      @var_select.set(@vars.keys.sort.reverse)
      @var_select.active
    end
    set_var
  end

  def draw_x
    gphys = @vars[@draw_data.gphys.name]
    dims = gphys.axnames
    index = Array.new(dims.length)
    dims.each_with_index{|dim,i|
      if dim==@x_name||dim==@y_name then
	index[i] = 0..-1
      else
	index[i] = @dims[dim].index
      end
    }
    @draw_data.gphys = gphys[*index]
    dims = @draw_data.gphys.axnames
    if (@draw_data.type!=LINE)&&(dims.index(@x_name)>dims.index(@y_name)) then
      @draw_data.transpose = true
    end

    @draw_data.axis_x.min = s2f(@x_min.get_text)
    @draw_data.axis_x.max = s2f(@x_max.get_text)
    @draw_data.axis_y.min = s2f(@y_min.get_text)
    @draw_data.axis_y.max = s2f(@y_max.get_text)

    x = @draw_data.gphys.coord(@x_name)
    if !@draw_data.axis_x.min then
      @draw_data.axis_x.min = x[0].val[0]
    end
    if !@draw_data.axis_x.max then
      @draw_data.axis_x.max = x[-1].val[0]
    end
    if @draw_data.type==LINE
      if !@draw_data.axis_y.min then
	@draw_data.axis_y.min = @draw_data.gphys.data.min
      end
      if !@draw_data.axis_y.max then
	@draw_data.axis_y.max = @draw_data.gphys.data.max
      end
    else
      y = @draw_data.gphys.coord(@y_name)
      if !@draw_data.axis_y.min then
	@draw_data.axis_y.min = y[0].val[0]
      end
      if !@draw_data.axis_y.max then
	@draw_data.axis_y.max = y[-1].val[0]
      end
    end

    if (min(@draw_data.axis_x.min,@draw_data.axis_x.max)<=0) and @draw_data.axis_x.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
    elsif (min(@draw_data.axis_y.min,@draw_data.axis_y.max)<=0) and @draw_data.axis_y.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
    else

      @draw = Draw.new if @draw.nil?

      @draw_data.axis_x.title=@x_title.get_text
      @draw_data.axis_x.unit=@x_unit.get_text
      @draw_data.axis_y.title=@y_title.get_text
      @draw_data.axis_y.unit=@y_unit.get_text
#      @draw_data.var.missing_value=@miss_entry.get_text
      @draw_data.title = @title_entry.get_text
      if @cont_level
	@draw_data.cont=[@cont_min_entry.get_text.to_f,@cont_interval_entry.get_text.to_f]
      else
	@draw_data.cont=nil
      end
      if @tone_level
	@draw_data.tone=[@tone_min_entry.get_text.to_f,@tone_interval_entry.get_text.to_f]
      else
	@draw_data.tone=nil
      end

      if @draw_data.type==MAP then
	p @map_combo.entry.get_text
	@draw_data.map_type=@maps.index(@map_combo.entry.get_text)+30
      end
      @save_code.set_sensitive(true)
      @save_image.set_sensitive(true)
      @draw.draw_x(@draw_data)
    end

  end

  def draw_next
    @dim_movie = @movie_combo.entry.get_text
    @dims[@dim_movie].next 
    draw_x
  end

# start
  def start
    Gtk.main
  end

# quit
  def file_close
    if @file then
      clear_var
      print _("file closed\n")
      @file.close
      @file = nil
      @vars.clear
      @dimtable.hide
      @dims.clear
    end
  end
  def finish
    file_close
    print _("Bye\n")
    Gtk.main_quit
  end

end


$main = GAVE.new
# argv

if ARGV[0] != nil then
  $main.file_open(ARGV.shift)
end

# main loop
$main.start
