; Copyright (c) 2003, Max Planck Institute for Aeronomy
;	Unauthorized reproduction prohibited.
;+
; CLASS_NAME:
;	data_properties_tab__define
;
; PURPOSE:
;	This is a template for plugin modules of the MURAM GUI tool.
;	Plugin modules are visible as tab widgets in a Display Window.
;
; SUPERCLASSES:
;       Inherits from the plugin class
;
; SUBCLASSES:
;       List classes that inherit from this class, if any.
;
; CREATION:
;       A plugin module is loaded with a Display Window with the following code:
;
; METHODS:
;       The following methods must be declared for a plugin module.
;
;	Update: A procedure for updating the tab in the Display Window belonging
;		to this plugin. This procedure is only called when this tab
;		is the currently selected one in the Display Window.
;
;	Refresh: A procedure for refreshing the tab in the Display Window.
;		When the Display Window is resized, this method is called.
;
;	GetProperty: to retrieve attributes of the plugin
;
;	SetProperty: to set attributes of the plugin
;
;	Init: The creation of the tab within the Display Window is handled in
;		this method. Widget in the tab for this plugin are usually created
;		in this method.
;
;
; MODIFICATION HISTORY:
; 	Written by:	Mark Cheung, May 2003.
;			Any additional mods get described here.  Remember to
;			change the stuff above if you add a new keyword or
;			something!

PRO data_properties_tab::Refresh, resize=resize

IF N_ELEMENTS(resize) EQ 0 THEN resize=0

; Error handling for all trapped errors.
Catch, theError
IF theError NE 0 THEN BEGIN
   Catch, /Cancel
   ok = Error_Message(Traceback=1, /Error)
   RETURN
ENDIF

self.DW->GetProperty, data_obj=data_obj

data_obj->GetProperty, $
	variable_name=variable_name, $
	unit = unit, $
	minValue = minValue, $
	maxValue = maxValue, $
	variable_object = variable_object
;variable_object->GetProperty, unit=unit

;widget_control, self.apply_button, get_uvalue=apply_button_state
;widget_control, apply_button_state.variable_name_field, set_value=variable_name
;widget_control, apply_button_state.unit_field, set_value = unit

IF resize THEN BEGIN
   widget_control, self.tab_ID, xsize=self.Tab_size[0], ysize=self.Tab_size[1]
   widget_control, self.left_base, xsize = 0.5*self.Tab_size[0]
   widget_control, self.right_base, xsize = 0.5*self.Tab_size[0]
   widget_control, self.bottom_base, xsize = self.Tab_size[0]
   widget_control, self.tab_ID, /realize;/update
   widget_control, self.left_base, /realize;/update
   widget_control, self.right_base, /realize;/update
   widget_control, self.bottom_base, /realize;/update
ENDIF

END

;==================================================================
; METHODNAME:
;       data_properties_tab::DrawPostscript
;
; PURPOSE:
;	Since IDL handles postscript and X devices differently,
;	this procedure is called when a user does a postscript save/
;	Generally, the code in this method is similar to that of Update.
;
; CALLING SEQUENCE:
;	data_properties_tab->DrawPostscript
;
;	
; MODIFICATION HISTORY:
; 	Written by:	Mark Cheung, May 2003
;	May, 2003	Any additional mods get described here.  Remember to
;			change the stuff above if you add a new keyword or
;			something!

PRO data_properties_tab::DrawPostscript

END

;==================================================================
; METHODNAME:
;       data_properties_tab::Update
;
; PURPOSE:
;	For updating the contours tab in the Display Window if it is currently selected
;	and some event (user-driven or not) occurs.
;
; CALLING SEQUENCE:
;	data_properties_tab->Update
;
;	
; MODIFICATION HISTORY:
; 	Written by:	Mark Cheung, May 2003
;	May, 2003	Any additional mods get described here.  Remember to
;			change the stuff above if you add a new keyword or
;			something!

PRO data_properties_tab::Update

 
END

; METHODNAME:
;       data_properties_tab::SetProperty
;
; PURPOSE:
;	For modifying the attributes of a contours_tab class object
;
; EXAMPLE:
;	The following example creates a Display_Window object named DW and retrives the
;	widget ID of the Display Window using the GetProperty function of this object.
;
;	plugin_temp = Obj_New("data_properties_tab", DW=DW)
;	plugin_temp->SetProperty, plugin_name="New Plugin Template"
;	
; MODIFICATION HISTORY:
; 	Written by:	Mark Cheung, May 2003
;	May, 2003	Any additional mods get described here.  Remember to
;			change the stuff above if you add a new keyword or
;			something!

PRO data_properties_tab::SetProperty, $
	plugin_name = plugin_name, $
	draw_canvas_size = draw_canvas_size

;Error Handling
Catch, theError
IF theError NE 0 THEN BEGIN
   Catch, Cancel=1
   ok = Dialog_Message('Error in SetProperty Method. Returning...')
   Print, ''
   Print, 'data_properties_tab::SetProperty Method: ' + !Error_State.Msg
ENDIF

IF N_ELEMENTS(plugin_name) NE 0 THEN self.plugin_name=plugin_name
IF N_ELEMENTS(draw_canvas_size) NE 0 THEN self.draw_canvas_size=draw_canvas_size

END

; METHODNAME:
;       data_properties_tab::GetProperty
;
; PURPOSE:
;	For the retrieval of information about the contours_tab object
;
; CALLING SEQUENCE:
;	plugin_temp = Obj_New("data_properties_tab", DW=DW)
;	plugin_temp->GetProperty, plugin_name=plugin_name, ...
;
; OPTIONAL INPUTS:
;	plugin_name : Returns the name of this plugin
;	tab_ID: Returns the widget ID of the tab associated with this plugin
;	drawID: Returns the widget ID of the draw widget contained in the contours tab.
;	DW : Returns an object pointer to the Display Window object to which
;		this plugin is attached.
;	draw_canvas_size: The size of the draw widget with widget ID drawID
;
; EXAMPLE:
;	plugin_temp = Obj_New("data_properties_tab", DW=DW)
;	plugin_temp->GetProperty, plugin_name=plugin_name, ...
;	
; MODIFICATION HISTORY:
; 	Written by:	Mark Cheung, May 2003
;	May, 2003	Any additional mods get described here.  Remember to
;			change the stuff above if you add a new keyword or
;			something!

PRO data_properties_tab::GetProperty, $
	plugin_name = plugin_name, $
	tab_ID = tab_ID, $
	DW = DW, $
	drawID = drawID, $
	draw_canvas_size = draw_canvas_size

;Error Handling
Catch, theError
IF theError NE 0 THEN BEGIN
   Catch, Cancel=1
   ok = Dialog_Message('Error in GetProperty Method. Returning...')
   Print, ''
   Print, 'contours_tab::GetProperty Method: ' + !Error_State.Msg
ENDIF

plugin_name = self.plugin_name
tab_ID = self.tab_ID
DW = self.DW
drawID = self.drawID
draw_canvas_size = self.draw_canvas_size

END

; METHODNAME:
;       data_properties_tab::Init
;
; PURPOSE:
;	For the creation of a the contours_tab plugin and its tab in a Display Window
;
; INPUTS:
;	DW: The Display Window Object to which this plugin is attached.
;
;
;
; EXAMPLE:
;	The following example creates a Display_Window object named DW and retrives the
;	widget ID of the Display Window using the GetProperty function of this object.
;
;	DW = Obj_New("Display_Window")
;	plugin_temp= Obj_New("data_properties_tab", DW=DW)
;	
; MODIFICATION HISTORY:
; 	Written by:	Mark Cheung, May 2003
;	May, 2003	Any additional mods get described here.  Remember to
;			change the stuff above if you add a new keyword or
;			something!

FUNCTION data_properties_tab::INIT, $
	DW=DW

;Error Handling
Catch, theError
IF theError NE 0 THEN BEGIN
   Catch, Cancel=1
   ok = Dialog_Message('Error in INIT Method. Returning...')
   Print, ''
   Print, 'data_properties_tab::INIT Method: ' + !Error_State.Msg
   RETURN, 0
ENDIF

IF N_ELEMENTS(tab_ID) EQ 0 THEN tab_ID=0L

;=====Pixel tab widget=================================
DW->GetProperty, $
	xsize=xsize, $			; x size of Display Window
	ysize=ysize, $			; y size of Display Window
	DW_ID=DW_ID, $			; Widget ID of Display Window
	DW_tabs=DW_tabs, $		; Widget ID of Tab widget in Display Window
	data_obj=data_obj

data_obj->GetProperty, $
	variable_name=variable_name, $
	dir = dir, $
	nmod = nmod, $
	filename = filename, $
	cube_size = cube_size, $
	minValue = minValue, $
	maxValue = maxValue, $
	variable_object = variable_object, $
	axes_units = axes_units, $
	dx_vec = dx_vec,$
	comments = comments

variable_object->GetProperty, unit=unit

tab_ID = widget_base(DW_tabs, Title="Data Properties", $
	xsize = xsize, ysize=ysize-70)
left_base = widget_base(tab_ID, xoffset=0, xsize=0.5*xsize, ysize=ysize-70-80, row=6)
right_base = widget_base(tab_ID, xoffset=0.5*xsize, xsize=0.5*xsize, ysize=ysize-70-80, row=5)
bottom_base = widget_base(tab_ID, yoffset = ysize-70-80, ysize=80, xsize=xsize)

dir_label = widget_label(left_base, value="Directory", xsize=0.2*xsize, /align_left)
dir_field = widget_text(left_base, value=dir, xsize=16)

filename_label = widget_label(left_base, value="Filename", xsize=0.2*xsize, /align_left)
filename_field = widget_text(left_base, value=filename, xsize=16)

nmod_label = widget_label(left_base, value="nmod", xsize=0.2*xsize, /align_left)
nmod_field = widget_text(left_base, value=nmod, xsize=16)

variable_name_label = widget_label(left_base, value="Variable Name", xsize=0.2*xsize, /align_left)
variable_name_field = widget_text(left_base, value=variable_name, /editable, xsize=16)

unit_label = widget_label(left_base, value="Unit", xsize=0.2*xsize, /align_left)
unit_field = widget_text(left_base, value=unit, /editable, xsize=16)

cube_size_label = widget_label(left_base, value="Cube size", xsize=0.2*xsize, /align_left)
cube_size_field = widget_text(left_base, value=strjoin(string(cube_size, format='(I3)'),','), xsize=16)

dx_vec_str = strjoin(string(dx_vec, format='(f6.2)'), ',')
dx_vec_label = widget_label(right_base, value="dx,dy,dz", xsize=0.2*xsize, /align_left)
dx_vec_field = widget_text(right_base, value=dx_vec_str, /editable, xsize=16)

axes_units_str = strjoin(axes_units, ',')
axes_units_label = widget_label(right_base, value="dx,dy,dz units", xsize=0.2*xsize, /align_left)
axes_units_field = widget_text(right_base, value=axes_units_str, /editable, xsize=16)

comments_label = widget_label(right_base, value="Comments", xsize=0.2*xsize, /align_left)
comments_field = widget_text(right_base, value=comments, /editable, /scroll, $
	 ysize=4, scr_ysize=60, xsize=25, /wrap)

file_select = fsc_fileselect(bottom_base, xsize=15, ObjectRef=file_select_Object)
;Check if dir has '/' as the last character. If not, append it to dir
last_char = strmid(dir, strlen(dir)-1, 1)
if (last_char ne '/') then dir = dir+'/'
IF nmod NE 'N/A' THEN dir=dir+nmod+'/'
file_select_Object->SetProperty, Directory=dir
IF filename NE 'N/A' THEN BEGIN
   file_select_Object->SetProperty, Filename=filename+'.hd'
ENDIF ELSE BEGIN
   file_select_Object->SetProperty, Filename='header'   
ENDELSE

create_header_button = widget_button(bottom_base, xoffset = 300, $
   value="Create Header", event_pro='data_properties_tab_events')

retrieve_header_button = widget_button(bottom_base, xoffset = 300, yoffset=40, $
   value="Retrieve Header", event_pro='data_properties_tab_events')

apply_button = widget_button(right_base, value="Apply Changes",$
   event_pro='data_properties_tab_events')
state = {apply_button:apply_button, $
	variable_name_field:variable_name_field, $
	unit_field:unit_field, $
	dx_vec_field:dx_vec_field, $
	dir_field:dir_field, $
	nmod_field:nmod_field, $
	axes_units_field:axes_units_field, $
	comments_field:comments_field, $
	file_select_Object:file_select_Object, $
	create_header_button:create_header_button, $
	retrieve_header_button:retrieve_header_button}

widget_control, apply_button, set_uvalue = state
widget_control, create_header_button, set_uvalue = state
widget_control, retrieve_header_button, set_uvalue = state

self.draw_canvas_size = [xsize,ysize-70]
self.tab_size = [xsize,ysize-70]
self.plugin_name='Data Properties'
self.drawID = 0L
self.tab_ID = tab_ID
self.DW = DW
self.apply_button = apply_button
self.left_base = left_base
self.right_base = right_base
self.bottom_base = bottom_base

;==============Need to store a pointer to this plugin object=======
;==============in the widget uvalue of tab_ID======================
widget_control, self.tab_ID, set_uvalue=self

RETURN, 1
END

PRO data_properties_tab__define

struct = {data_properties_tab, $
	drawID:0L, $			; The widget ID of the draw canvas
	draw_canvas_size:intarr(2), $	; The [width,height] of the draw widget with ID=drawID
	apply_button:0L, $		; Widget ID of Apply Button
	left_base:0L, $			; Widget ID of LHS base widget
	right_base:0L, $		; Widget ID of RHS base widget
	bottom_base:0L, $		; Widget ID of bottom base widget
	INHERITS plugin $		; Inherit methods and attributes from class "plugin"
	}
END

;========================================================================
;=================External procedures for event handling=================

PRO data_properties_tab_events, event

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_BUTTON') THEN BEGIN
   widget_control, event.id, get_value = button_label

   CASE button_label OF
	'Apply Changes': BEGIN
	   widget_control, event.id, get_uvalue=apply_button_state
	   widget_control, apply_button_state.variable_name_field, get_value=variable_name
	   widget_control, apply_button_state.unit_field, get_value=unit
	   widget_control, apply_button_state.dx_vec_field, get_value=dx_vec_str
	   widget_control, apply_button_state.axes_units_field, get_value=axes_units_str
	   widget_control, apply_button_state.comments_field, get_value=comments
	   widget_control, apply_button_state.nmod_field, get_value=nmod

	   tab_ID = widget_info(widget_info(event.id, /parent), /parent)
	   widget_control, tab_ID, get_uvalue = data_properties_tab_plugin
	   data_properties_tab_plugin->GetProperty, DW=DW
	   DW->GetProperty, data_obj=data_obj, colorbar=colorbar, DW_ID=DW_ID

	   axes_units = strarr(3)
	   axes_units = strsplit(axes_units_str, ',', /extract)
	   dx_vec = fltarr(3)
	   dx_vec = float(strsplit(dx_vec_str, ',', /extract))
	   data_obj->SetProperty, variable_name=variable_name, unit=unit, $
		axes_units=axes_units, dx_vec=dx_vec, comments=comments
	   colorbar->SetProperty, Title=(variable_name+' ('+unit+')')
	   ; Change window title
	   Widget_Control, DW_ID, TLB_Set_Title=variable_name	   
	END

	"Create Header": BEGIN
	   widget_control, event.id, get_uvalue=state
	   widget_control, event.top, get_uvalue=DW
	   DW->GetProperty, main_ID = main_ID, data_obj=data_obj
	   data_obj->GetProperty, cube_size = cube_size
	   cube_size = string(cube_size, format='(I4)')
	   size = cube_size[0]+','+cube_size[1]+','+cube_size[2]
	   
	   state.file_Select_object->GetProperty, filename=filename, dir=dir

	   widget_control, state.variable_name_field, get_value=variable_name
	   widget_control, state.unit_field, get_value=unit
	   widget_control, state.dx_vec_field, get_value=dx_vec_str
	   widget_control, state.axes_units_field, get_value=axes_units_str
	   widget_control, state.comments_field, get_value=comments
	   widget_control, state.nmod_field, get_value=nmod

	   ;Concatenate comment lines
	   comments = strjoin(comments[*], ' ')
	   
	   ;Check if dir has '/' as the last character. If not, append it to dir
	   last_char = strmid(dir, strlen(dir)-1, 1)
	   if (last_char ne '/') then dir = dir+'/'

;	   IF filename NE 'N/A' and $
;		(strmid(dir, strlen(filename)-3, 3) NE '.hd' ) THEN BEGIN
	  ;    filename=filename+'.hd'
	 ;  ENDIF ELSE BEGIN
   	;	filename='header'
	   ;ENDELSE

	   ;=========See if file already exists=============
	   answer = ''
	   close, 7
	   openr, 7, dir+filename, error=read_error
	   IF read_error EQ 0 THEN BEGIN
		answer = Dialog_Message(dir+filename+' already exists, overwrite?', /question, /default_no)
		print, answer
	   ENDIF
	   ;=========Open file to write header file=========
	   close, 7
	   openw, 7, dir+filename, error=write_error
	   IF (write_error EQ 0) AND (answer EQ 'Yes') THEN BEGIN
		printf, 7, 'variable_name<~>'+variable_name
		printf, 7, 'unit<~>'+unit
		printf, 7, 'size<~>'+size
		printf, 7, 'dx_vec<~>'+dx_vec_str
		printf, 7, 'axes_units<~>'+axes_units_str
		printf, 7, 'comments<~>'+comments
		printf, 7, 'nmod<~>'+nmod
		close, 7
		log_entry, main_ID, 'Wrote header file to: '+dir+filename
	   ENDIF ELSE BEGIN
		IF answer EQ 'Yes' THEN BEGIN
		   ok = Dialog_Message('Error writing header file.'+!Error_State.Msg)
		   Print, ''
   		   Print, 'Error writing header file: ' + !Error_State.Msg
		ENDIF
	   ENDELSE
	   close, 7
	END

	'Retrieve Header': BEGIN

	   widget_control, event.id, get_uvalue=state
	   widget_control, event.top, get_uvalue=DW
	   DW->GetProperty, main_ID = main_ID
	   state.file_Select_object->GetProperty, filename=filename, dir=dir

	   ;widget_control, state.variable_name_field, get_value=variable_name
	   ;widget_control, state.unit_field, get_value=unit
	   ;widget_control, state.dx_vec_field, get_value=dx_vec_str
	   ;widget_control, state.axes_units_field, get_value=axes_units_str
	   ;widget_control, state.comments_field, get_value=comments
	   ;widget_control, state.nmod_field, get_value=nmod

	   filename = state.file_Select_object->GetFilename()
	   ;last_char = strmid(dir, strlen(dir)-1, 1)
	   ;if (last_char ne '/') then dir = dir+'/'
	   ;IF nmod NE 'N/A' THEN dir=dir+nmod+'/'
	   print, filename

	   close, 7
	   openr, 7, filename, error=read_error

	   IF read_error EQ 0 THEN BEGIN
		lines = strarr(20)
		fields = strarr(20)
		values = strarr(20)
		i = 0
		WHILE NOT(EOF(7)) AND (i LE 20) DO BEGIN
		   line = '' & READF, 7, line
		   split_line = strsplit(line, '<~>', /extract)
		   IF (N_ELEMENTS(split_line) EQ 2) THEN BEGIN
		      fields[i] = split_line[0]
		      values[i] = split_line[1]
		      i=i+1
		   ENDIF
		ENDWHILE
		IF ((where(fields EQ 'variable_name'))[0] NE -1) THEN variable_name = values[where(fields EQ 'variable_name')]
		IF ((where(fields EQ 'unit'))[0] NE -1) THEN unit = values[where(fields EQ 'unit')]
		IF ((where(fields EQ 'dx_vec'))[0] NE -1) THEN dx_vec_str = values[where(fields EQ 'dx_vec')]
		IF ((where(fields EQ 'axes_units'))[0] NE -1) THEN axes_units_str = values[where(fields EQ 'axes_units')]
		IF ((where(fields EQ 'nmod'))[0] NE -1) THEN nmod = values[where(fields EQ 'nmod')]
		IF ((where(fields EQ 'comments'))[0] NE -1) THEN comments = values[where(fields EQ 'comments')]

		widget_control, state.variable_name_field, set_value=variable_name
		widget_control, state.unit_field, set_value=unit
	   	widget_control, state.dx_vec_field, set_value=dx_vec_str
	   	widget_control, state.axes_units_field, set_value=axes_units_str
	   	widget_control, state.comments_field, set_value=comments
	   	widget_control, state.nmod_field, set_value=nmod


		print, fields, values
		
	   ENDIF
	END

	ELSE:BEGIN
	END
   ENDCASE

ENDIF

END
