;+
; NAME:
;       HW_DATA__DEFINE
;
; PURPOSE:
;       The hw_data object is the generalized superclass for data
;       class objects used by the Hansteen/Wikstøl QL/data analysis
;       SW. All data (independent of source) following this structure
;       can use the Hansteen/Wikstøl SW for visualization and analysis.
;
;       For a specific source of a data, a new class must be defined
;       (i.e. eis_data__define.pro for SOLAR-B EIS instrument). This class
;       inherits the hw_data superclass. The data class must
;       provide a read-routine for reading the specific data
;       (i.e. eis_data__read.pro).
;
;
; CATEGORY:
;       Hansteen/Wikstol Data analysis SW
;
; CALLING SEQUENCE:
;
;
; INPUTS:
;      None
;
; KEYWORD PARAMETERS:
;
;
; OUTPUTS:
;       Objects of class HW_DATA includes the following parameters:
;
;       nx        Number of wavelength pixels
;       ny        Number of pixels along the slit
;       nraster   Number of raster posistions
;       nwin      Number of wavelength windows on detector
;       ccd_sz    Size of CCD [wavelength, slit]
;       xs[nwin]  Pixel start position of window along wavelength
;       xw[nwin]  Pixel Width of window along wavelength
;       ys[nwin]  Pixel start position of window along the slit
;       yw[nwin]  Pixel width of window allong the slit
;       w[nwin]   Array of pointers to the nwin numbers of pixel data
;       unit:     String describing data units (e.g. ['Counts/pixel']
;       wid:      Line ID string for each data window 
;                 (e.g. 'Fe IX 195.03 Å')
;
; CALLS:
;
;
; COMMON BLOCKS:
;
;
; PROCEDURE:
;       Defines the structure of data class objects.
;
; RESTRICTIONS:
;
;
; MODIFICATION HISTORY:
;       XX-Aug-2001: Viggo Hansteen
;       20-Sep-2001: Oivind Wikstol - Added documentation.
;       22-Jan-2003: Oivind Wikstol - Removed nx and ny, as they were the same as xw
;                                     and yw (width of line windows in pixels 
;                                     in x and y direction)
;       23-Feb-2004: Oivind Wikstol - Added wid to object: Line
;                                     IDs. Added methods to get and
;                                     set wid.
;        5-May-2004: Oivind Wikstol - Added save method
;       11-May-2004: Oivind Wikstol - Added setnwin method. Added 'unit'
;                                     to hw_data struct.
;       15-Dec-2005: Oivind Wikstol - Added home institution. Name of institution
;                                     where software is run.
;       10-Feb-2007: Viggo Hansteen - Added help methods.
;       29-Sep-2007: A. Gardini     - Pointers cleanup.
;        5-Dec-2007: A. Gardini     - Cleanup of self.w modified.
;        3-Jul-2008: A. Gardini     - Added HELP and INIT_HW_METHODS methods.
;    
; $Id: hw_data__define.pro 405 2010-07-04 11:21:38Z viggoh $
;
;-
function hw_data::init
  self->init_hw_methods ; initialization of the help method
  self.help=obj_new('hw_help')
  self.title='HW Data'
  self.aspect=1.0
  return,1
end

pro hw_data::cleanup
  obj_destroy,self.help
end

pro hw_data::display_all,init=init
  if n_elements(init) eq 1 then return
  self.help->display_all
  return
end

pro hw_data::display_methods,init=init
  if n_elements(init) eq 1 then return
  self.help->display_methods
  return
end

pro hw_data::read,file,init=init
  if n_elements(init) eq 1 then return
end

pro hw_data::save, file,init=init
  if n_elements(init) eq 1 then return
end

function hw_data::gethome_inst,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.home_inst
end

pro hw_data::setxw,xw,init=init
  if n_elements(init) eq 1 then return
  self.xw=xw
end

function hw_data::getxw,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.xw
end

function hw_data::getxs,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.xs
end

function hw_data::getys,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.ys
end

function hw_data::getyw,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.yw
end


function hw_data::getnexp,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.nexp
end

pro hw_data::setnexp,nexp,init=init
  if n_elements(init) eq 1 then return
  self.nexp=nexp
end

function hw_data::getnraster,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.nraster
end

function hw_data::getntime,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.ntime
end

function hw_data::getnwin,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.nwin
end

pro hw_data::setnwin, nwin,init=init
  if n_elements(init) eq 1 then return
  self.nwin = nwin
end

function hw_data::gettitle,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.title
end

function hw_data::getcomment,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.comment
end

pro hw_data::setaspect, aspect,init=init
  if n_elements(init) eq 1 then return
  self.aspect = aspect
end

function hw_data::getaspect,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.aspect
end

function hw_data::getdatasource,init=init
  if n_elements(init) eq 1 then return,-1
  return, self.datasource
end

pro hw_data::getwin,win,wd,pos,init=init
  if n_elements(init) eq 1 then return
          ; get window win, into wd, position pos on ccd
  wd=*self.w[win]
  pos=[self.xs[win], self.xw[win], self.ys[win], self.yw[win]]
  return
end

function hw_data::setwid, win, wid,init=init
  if n_elements(init) eq 1 then return,-1
  self.wid[win] = wid
end

function hw_data::getvar,win,init=init
  if n_elements(init) eq 1 then return,-1
  if n_elements(win) eq 0 then win=0
           ; return window win
  if ptr_valid(self.w[win]) then return,*self.w[win] else return,-1
end

function hw_data::getexp,init=init
  if n_elements(init) eq 1 then return,-1
  return,*self.exp
end

pro hw_data::setcomment, str,init=init
  if n_elements(init) eq 1 then return
  self.comment = str
end

pro hw_data::setupvar,w,win,init=init
  if n_elements(init) eq 1 then return
  self.w[win]=ptr_new(w)
end

pro hw_data::setvar,w,win,init=init
  if n_elements(init) eq 1 then return
  *self.w[win]=w
end

function hw_data::gethdr,init=init
  if n_elements(init) eq 1 then return,-1
  return,*self.hdr
end

function hw_data::getaux,init=init
  if n_elements(init) eq 1 then return,-1
  return,*self.aux
end

pro hw_data::setunit,unit,init=init
  if n_elements(init) eq 1 then return
  self.unit=unit
end

function hw_data::getunit,string=string,init=init
  if n_elements(init) eq 1 then return,-1
  if n_elements(string) eq 0 then string=0
  if string then return,(self.unit)[0] else return,self.unit
end

pro hw_data::help
  help,self,/obj
  return
end

pro hw_data::init_hw_methods

  self->display_all,/init
  self->display_methods,/init
  self->read,/init
  self->save,/init
  a=self->gethome_inst(/init)
  self->setxw,/init
  a=self->getxw(/init)
  a=self->getxs(/init)
  a=self->getys(/init)
  a=self->getyw(/init)
  a=self->getnexp(/init)
  self->setnexp,/init
  a=self->getnraster(/init)
  a=self->getntime(/init)
  a=self->getnwin(/init)
  self->setnwin,/init
  a=self->gettitle(/init)
  a=self->getcomment(/init)
  self->setaspect,/init
  a=self->getaspect(/init)
  a=self->getdatasource(/init)
  self->getwin,/init
  a=self->setwid(/init)
  a=self->getvar(/init)
  a=self->getexp(/init)
  self->setcomment,/init
  self->setupvar,/init
  self->setvar,/init
  a=self->gethdr(/init)
  a=self->getaux(/init)
  self->setunit,/init
  a=self->getunit(/init)

  return
end

pro hw_data::cleanup  
  obj_destroy,self.help
  if ptr_valid(self.aux) then begin
    obj_destroy,*self.aux
    ptr_free,self.aux
  endif
  if ptr_valid(self.hdr) then begin
    obj_destroy,*self.hdr
    ptr_free,self.hdr
  endif
; for i=0,self.nwin-1 do ptr_free,self.w[i]
  ptr_free,self.w[where(ptr_valid(self.w))]
  ptr_free,self.exp 
end

pro hw_data__define
  nwin=25
  struct={hw_data, $
          title:'', $
          comment:'', $
          help:obj_new(), $
          home_inst:'',$
          datasource:'',$
;         hdr:ptr_new(obj_new()),$
;         aux:ptr_new(obj_new()),$
          hdr:ptr_new(),$ ; This definition prevents the dangling pointer
          aux:ptr_new(),$ ; This definition prevents the dangling pointer
          nexp:0UL, $
          nraster:0, $
          ntime:0,  $
          nwin:nwin, $
          aspect:1.0, $
          exp:ptr_new(), $
          xs:intarr(nwin),  $
          xw:intarr(nwin),  $
          ys:intarr(nwin),  $
          yw:intarr(nwin),  $
          w:ptrarr(nwin), $
          wid:strarr(nwin), $
          unit:strarr(3)}
end

