;$id$
;###############################################################################
; LICENSE:
;  The software in this file is written by an employee of 
;  National Institute of Standards and Technology 
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used of if the code in this file is
;  included in another product.
;
;###############################################################################
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
function oData::get $
	, qty = qty $
	, err = err $
	, vol = vol $
	, xdata = x $
	, ydata = y

	if n_elements( *self.qty ) eq 0 then return, 0
	qty = *self.qty
	err = *self.err
	vol = *self.vol
	x = *self.x
	y = *self.y

	return, 1

end
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
function oData::set $
	, qty = qty $
	, err = err $
	, vol = vol $
	, xdata = x $
	, ydata = y $
	, no_copy = no_copy $
	, _extra=_extra

	if n_elements( qty ) ne 0 then begin
		if keyword_set( no_copy ) then begin
			ptr_free, self.qty
			self.qty = ptr_new( qty, /no_copy )
		endif else $
			*self.qty = qty
	endif

	if n_elements( err ) ne 0 then begin
		if keyword_set( no_copy ) then begin
			ptr_free, self.err
			self.err = ptr_new( err, /no_copy )
		endif else *self.err = err
	endif

	if n_elements( vol ) ne 0 then begin
		if keyword_set( no_copy ) then begin
			ptr_free, self.vol
			self.vol = ptr_new( vol, /no_copy )
		endif else *self.vol = vol
	endif

	if n_elements( x ) ne 0 then begin
		if keyword_set( no_copy ) then begin
			ptr_free, self.x
			self.x = ptr_new( x, /no_copy )
		endif else *self.x = x
	endif

	if n_elements( y ) ne 0 then begin
		if keyword_set( no_copy ) then begin
			ptr_free, self.y
			self.y = ptr_new( y, /no_copy )
		endif else *self.y = y
	endif

	self -> _set_fill_in
	return, self -> _set_consistency_check()

end
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
function oData::init, _extra=_extra

	self.qty = ptr_new(/allocate_heap)
	self.err = ptr_new(/allocate_heap)
	self.vol = ptr_new(/allocate_heap)
	self.x = ptr_new(/allocate_heap)
	self.y = ptr_new(/allocate_heap)

	return, self -> set( _extra = _extra )

end
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
pro oData::cleanup

	ptr_free, self.qty
	ptr_free, self.err
	ptr_free, self.vol
	ptr_free, self.x
	ptr_free, self.y

end
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
pro oData::_set_fill_in

	n_qty = n_elements( *self.qty )
	message, 'n_qty is ' + string( n_qty ), /continue
	if n_qty eq 0 then return

	size_qty = size( *self.qty )

	n_err = n_elements( *self.err )
	n_vol = n_elements( *self.vol )
	n_x = n_elements( *self.x )
	n_y = n_elements( *self.y )

	if n_err eq 0 then begin
		*self.err = *self.qty
		(*self.err)[*] = 0d
	endif

	if n_vol eq 0 then begin
		*self.vol = *self.qty
		(*self.vol)[*] = 1d
	endif

	if n_x eq 0 then begin
		case size_qty[0] of
			0: *self.x = 0
			else: *self.x = dindgen( size_qty[1] )
		endcase
	endif

	if n_y eq 0 then begin
		case size_qty[0] of
			0: *self.y = 0
			1: *self.y = dblarr( size_qty[1] )
			else: *self.y = dindgen( size_qty[2] )
		endcase
	endif

 	; Change the dimension of arrays if necessary.
 	; Note that the following procedure only saves
 	; the extra (unecessary) dimension to the pointers.
 	if size_qty[0] eq 2 then begin
 		void = array_oned2twod( *self.x, *self.y, x_2d, y_2d )
 		ptr_free, [ self.x, self.y ]
 		self.x = ptr_new( x_2d, /no_copy )
 		self.y = ptr_new( y_2d, /no_copy )
 	endif

end
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
function oData::_set_consistency_check

	if n_elements( *self.qty ) eq 0 then return, 0

	qty_size = size( *self.qty )
	err_size = size( *self.err )
	vol_size = size( *self.vol )
	x_size = size( *self.x )
	y_size = size( *self.y )

	if not array_equal_dimension( self.qty, self.err ) then begin
		message, 'self.qty and self.err are not compatible.', /continue
		return, 0
	endif
	if not array_equal_dimension( self.qty, self.vol ) then begin
		message, 'self.qty and self.vol not compatible.', /continue
		return, 0
	endif
	if not array_equal_dimension( self.x, self.y ) then begin
		message, 'self.x and self.y not compatible.', /continue
		return, 0
	endif
	if not array_equal_dimension( self.qty, self.x, /histo) then begin
		message, 'self.qty and self.x not compatible.', /continue
		return, 0
	endif

	return, 1

end
;*******************************************************************************
;23456789 123456789 123456789 123465798 123456789 123456789 123465789 123456789
;       10        20        30        40        50        60        70        80
;*******************************************************************************
;
; It is assumed that qty is less than or equal to 2D.
;
pro oData__define

	void = { oData $
		; External
		, qty:ptr_new() $
		, err:ptr_new() $
		, vol:ptr_new() $
		, x:ptr_new() $
		, y:ptr_new() $
		}

end
