; MODULE 1D data retrieval

;+
; NAME:
;	Init_Data
; PURPOSE:
;	Initialize the plot table and the structures used by mdisp.
; CATEGORY:
;	Data Management
; CALLING SEQUENCE:
; 	Init_Data
; SIDE EFFECT:
;	The old plot table is erased.
;
; MODIFICATION HISTORY:
;	Created in June 1991 by A.Csillaghy
;		Inst. of Astronomy, ETH Zurich
;	Structures modified in November 91 a. Cs
;-


;+
; NAME: 
;	Load Plot
; PURPOSE: 
;	Loads a plot from the plot table.
; CALLING SEQUENCE:
;	LoadPlot, name [, length , x,y,qual, dx, dy, 
;		title, xTitle, yTitle, text, color, linestyle,
;		thick,  offset,  subTitle, overallQual, symsize ]
; INPUT:
;	name: a string or array of string
; OUTPUTS:
;	length: the length of the relevant data
;	x, y: the plot values. To plot correctly the i-th plot loaded, ;	;		type
;		Plot, x(0:length(i-1),i), y(0:length(i)-1,i)
;		or
;		Data_display, x, y, LENGTH = length
; 	dx, dy: the errors in x- and y-directions
;	title, xTitle, yTitle, text, color, linestyle, thick,  offset,  
;	subTitle, overallQual, symsize: attributes of the plots loaded
; RESTRICTION:
;	Works only after running init_data.pro
; REMARK:
;	For better description of the parameters, see "data_display"
;	or 
;-

PRO LoadPlot, name, length, x, y, qual, dx, dy, $
	title,  xTitle,  yTitle,  text,  color, $
 	lineStyle,  thick,  offset,  subTitle, overallQual, symsize

  COMMON Data, plotList, vectorTable

  idx = Where( plotList.name EQ name )
  IF Total(idx) EQ -1 THEN BEGIN
     Error, 14, 'Load Plot'
     RETURN
  ENDIF

  item = plotList( idx )

  length = item.len
  x = vectorTable( *, item.values.x )
  y = vectorTable( *, item.values.y )
  qual = vectorTable( *, item.qual )
  dx = [ [vectorTable( *, item.errors.x.left )] , $
	 [vectorTable( *, item.errors.x.right )]  ]
  dy = [ [vectorTable( *, item.errors.y.left )] , $
	 [vectorTable( *, item.errors.y.right )]  ]
  title = item.texts.mainTitle
  subTitle = item.texts.subTitle
  text = item.texts.text
  xTitle = item.texts.title.x
  yTitle = item.texts.title.y
  overallQual = item.overallQual
  color = item.color
  lineStyle = vectorTable( *, item.lineStyle )
  thick = item.thick
  offset = item.offset
  qual = item.qual
  symsize = item.symsize

END ; Load Plot

  
;+
; NAME: 
;	Init Selection
; PURPOSE: 
;	Initializes the selection list (or resets it)
; CALLING SEQUENCE: 
; 	InitSel
; RESTRICTION:
;	Works only after running init_data.pro
;-

PRO InitSel

  COMMON SelectionRetrieval, plotsSelected

  plotsSelected = ''

END


;+
; NAME: 
;	Get Names
; PURPOSE: 
;	Returns an array of strings containing the names of
;	the plots stored in the plot table, or in the selection.
; CALLING SEQUENCE: 
; 	result = Get_Names()
; KEYWORD: 
;	SELECTION: If set only the names in the selection list ;	;		are returned.
;-

FUNCTION GetNames, SELECTION = selection


  COMMON SelectionRetrieval, plotsSelected
  COMMON Data, plotList, dummy
 
  IF NOT Keyword_Set(SELECTION) THEN BEGIN
    IF No_Data() THEN RETURN, '' $
    ELSE RETURN, plotList(1:N_Elements(plotList)-1).name
  ENDIF ELSE BEGIN
    nbSel = N_Selected()
    IF nbSel LE 0 THEN RETURN, '' $
    ELSE RETURN, plotsSelected
  ENDELSE

END ; Get Names


PRO Insert, vector, vectorTable, tableSize, index

; Inserts a vector in the vector table.

  nbEls = N_Elements(vector)
  tableLen = N_Elements(vectorTable(*,0))
    IF nbEls GT tableLen THEN BEGIN
       AdjustTable, vectorTable, nbEls
       tableLen = nbEls
    ENDIF ELSE IF nbEls LT tableLen THEN BEGIN
       newVector = Replicate( 0.0, tableLen )
       newVector(0) = vector 
       vector = newVector
    ENDIF
    index = 0 &  done = 0

    WHILE (index  LT tableSize) AND  (done EQ 0) DO BEGIN
      IF Total(vector EQ vectorTable(*,index) ) NE  tableLen $
	  THEN index = index+1 $
      ELSE done = 1
    ENDWHILE
    IF index EQ tableSize THEN BEGIN
       vectorTable = [ [vectorTable], [vector] ]
       tableSize = tableSize+1
    ENDIF

END ; Insert


PRO InsertArr, vectArr, vectorTable, tableSize, listEl, $
	XVAL = xVal, YVAL = yVal, QUAL = qual, $
	DXL = dxl, DXR = dxr, LS = ls, $
	DYU = dyu, DYD = dyd, USERSYM = userSym

; WARNING: only ONE keyword must be used at the same time.

    nbVect = N_Elements(vectArr(0,*))
    IF nbVect NE 0 THEN BEGIN
      FOR i = 0,nbVect-1 DO BEGIN
        Insert, vectArr(*,i), vectorTable, tableSize,index
        CASE 1 OF
          Keyword_Set( XVAL ) : listEl(i).values.x = index
          Keyword_Set( YVAL ) : listEl(i).values.y = index
          Keyword_Set( QUAL ) : listEl(i).qual = index
          Keyword_Set( DXL ) : listEl(i).errors.x.left = index
          Keyword_Set( DXR ) : listEl(i).errors.x.right = index
          Keyword_Set( DYU ) : listEl(i).errors.y.left = index
          Keyword_Set( DYD ) : listEl(i).errors.y.right = index
          Keyword_Set( USERSYM ) : listEl(i).userSym = index
          Keyword_Set( LS ): listEl(i).lineStyle = index
        ENDCASE
      ENDFOR
    ENDIF
END ; InsertArr


FUNCTION SearchPlot,name

;+
; NAME:
; 	Search Plot
; PURPOSE:
;	Returns the index of a plot in the plot list
; CALLIG SEQUENCE:
; 	result = SearchPlot( name )
; INPUT:
;	name: a string scalar
; RESULT OF FUNCTION:
;	-1: there is no plot in the plot list
;	0: there are plots in the plot list, but not with this name
;	else: the plot number in the plot list.
; RESTRICTION:
;	works only after runnig init_data.pro
;-

  COMMON Data, plotList, dummy

  n = N_Elements( plotList )
  IF n LE 1 THEN RETURN, -1
  namesList = plotList( 1: n-1 ).name

  i = N_Elements( name )-1
  IF i LT 0  THEN RETURN, -1

  res = Where( namesList EQ name(i) ) + 1

  WHILE i GT 0 DO BEGIN
    i = i-1
    res = [ res, Where( namesList EQ name(i) ) + 1 ]
  ENDWHILE

  IF N_Elements( res ) GT 1 THEN BEGIN
    validIdx = Where( res GT 0 )
    IF validIdx(0) NE -1 THEN RETURN, res( Where( res GT 0 )) $
    ELSE RETURN, 0
  ENDIF  ELSE RETURN, res

END ; search plot

;+
; NAME: 
;	Insert Plot 
; PURPOSE: 
;	Inserts a plot in the plot table
; CALLING SEQUENCE:
;	 InsertPlot, name, len [, x, y, qual, dx, dy, 
;		color, lineStyle, thick, offset, overallQual, 
;		userSym, title, xTitle,  yTitle,  subtitle, text,
;		symsize]
; INPUTS:
;	name: a string array or scalar
;	len: the number of elements of the plot
; 	 x, y, qual, dx, dy: the plot description (see data_display)
;	color, lineStyle, thick, offset, overallQual, 
;	userSym, title, xTitle,  yTitle,  subtitle, text,
;	symsize: the attributes of the plot (see  ... )
; KEYWORD: 
;	NEW: to set if the plot is not already inserted. Otherwise, 
;		the parameters given are taken as complemental
;		information to an already existing plot.
; RESTRICTION:
;	works only after running init_data
; MODIFICATION HISTORY:
;	Fixed a bug with doublenameslst in Oct 95, ACs
;-

PRO InsertPlot, name, len, x, y, qual, dx, dy,  $
	color, lineStyle, thick, offset, overallQual,  userSym, $
	title, xTitle,  yTitle,  subtitle, text, symsize, NEW = new

  COMMON Notation, v
  COMMON Data, plotList, vectorTable

  IF N_Elements( v ) EQ 0 THEN v = 1
  IF N_Elements( name ) EQ 0 THEN BEGIN
    name = 'No Name' 
    nbEls = 1
  ENDIF ELSE nbEls = N_Elements( name )

  plotNr = SearchPlot( name )

  IF NOT Keyword_Set( NEW ) AND (Total(plotNr) EQ 0) $
	THEN BEGIN
    Error, 8, 'Insert Plot'
    RETURN
  ENDIF ELSE IF Keyword_Set( NEW ) THEN BEGIN
    IF N_Elements(v) EQ 0 THEN v = 1
    IF Total(plotNr) GE 1 THEN BEGIN
      doubleNamesLst = -1
      FOR  i = 0,nbels-1 DO BEGIN
	doubleNamesLst = [ doubleNamesLst, $
	  Where( name(i) EQ plotList( plotNr ).name ) ]
      ENDFOR
      tempIdx = Where( doubleNamesLst NE -1 )
      IF Total( tempIdx ) NE -1 THEN BEGIN
        doubleNamesLst = doubleNamesLst( tempIdx )
        name( doubleNamesLst )= $
	  name( doubleNamesLst )+'_v'+StrTrim(v,2)
        v = v+1
      ENDIF
    ENDIF
    p = Replicate( {plotType}, nbEls )
    FOR i = 0,nbEls-1 DO BEGIN
      p(i).name = name(i)
      p(i).len = len(i)
    ENDFOR
  ENDIF ELSE p = plotlist( plotNr )

  tableSize = N_Elements( vectorTable(0,*) )
  tagNames = Tag_Names( p )
  first = Where( tagNames EQ 'X' )
  IF N_Elements( x ) NE 0 THEN $
	 InsertArr, x , vectorTable, tableSize, p, /XVAL
  IF N_Elements( y ) NE 0  THEN $
	 InsertArr, y, vectorTable, tableSize, p, /YVAL
  IF N_Elements( qual ) NE 0 THEN $
	InsertArr,qual , vectorTable, tableSize, p, /QUAL
  IF N_Elements( lineStyle ) NE 0 THEN $
	InsertArr,lineStyle , vectorTable, tableSize, p, /LS
  IF N_Elements( userSym ) NE 0  THEN $
	InsertArr, userSym, vectorTable, tableSize, p, /USERSYM
  IF N_Elements( dx ) NE 0 THEN BEGIN
    InsertArr, dx(*, 0), vectorTable, tableSize, p, /DXL
    siz = Size( dx )
    IF  (siz(0) GT 2) OR (siz(0) EQ 2 AND nbEls EQ 1) THEN BEGIN
      IF nbEls EQ 1 THEN InsertArr, dx(*,1), vectorTable, tableSize, p, /DXR $
      ELSE InsertArr, dx(*, *, 1), vectorTable, tableSize, p, /DXR 
    ENDIF
  ENDIF
  IF N_Elements( dy ) NE 0  THEN  BEGIN
    InsertArr, dy(*,0), vectorTable, tableSize, p, /DYU
    siz = Size( dy )
    IF  (siz(0) GT 2) OR (siz(0) EQ 2 AND nbEls EQ 1) THEN  BEGIN
      IF nbEls EQ 1 THEN InsertArr, dy(*,1), vectorTable, tableSize, p, /DYD $
      ELSE InsertArr, dy(*, *, 1), vectorTable, tableSize, p, /DYD 
    ENDIF
  ENDIF

  IF N_Elements( title ) NE 0 THEN $
      	FOR i = 0, nbEls-1 DO p(i).texts.mainTitle = title(i)
  IF N_Elements( subTitle ) NE 0  THEN $
      	FOR i = 0, nbEls-1 DO p(i).texts.subTitle = subTitle(i)
  IF N_Elements( xTitle ) NE 0  THEN $
    	FOR i = 0, nbEls-1 DO p(i).texts.title.x = xtitle(i)
  IF N_Elements( yTitle ) NE 0  THEN $
    	FOR i = 0, nbEls-1 DO p(i).texts.title.y = ytitle(i)
  IF N_Elements( text ) NE 0  THEN $
    	FOR i = 0, nbEls-1 DO p(i).texts.text = text(i)
  IF N_Elements( color ) NE 0  THEN $
    	FOR i = 0, nbEls-1 DO p(i).color = color(i) $
  ELSE FOR i = 0, nbEls-1 DO p(i).color = 255B
  IF N_Elements( thick ) NE 0 THEN $
	FOR i = 0, nbEls-1 DO p(i).thick = thick(i)
  IF N_Elements( offset ) NE 0 THEN $
	FOR i = 0, nbEls-1 DO p(i).offset = offset(i)
  IF N_Elements( overallQual ) NE 0  THEN $
	FOR i = 0, nbEls-1 DO p(i).overallQual = overallQual(i)
  IF N_Elements( symsize ) NE 0  THEN $
	FOR i = 0, nbEls-1 DO p(i).symsize = symsize(i)

  IF Keyword_Set( NEW ) THEN plotlist = [ plotList, p ] $
  ELSE FOR i = 0, nbEls-1 DO $
    plotList( Where( plotList.name EQ p(i).name ) ) = p(i)

END 

;+
; NAME: Insert in the Selection
; PURPOSE:  Adds plots to the selection list
; CALLING SEQUENCE:
;	InsertSel, names
;-
PRO InsertSel, names

  COMMON SelectionRetrieval, plotsSelected

  nbEls = N_Elements( plotsSelected )
  IF nbEls EQ 0 THEN plotsSelected = names $
  ELSE IF nbEls EQ 1 AND plotsSelected(0) EQ '' THEN $
    plotsSelected = names $
  ELSE plotsSelected = [ plotsSelected, names ]

END ; insert sel

;+
; NAME: Load Selection
; PURPOSE: Loads in variables the data related to the plots selectioned.
; CALLING SEQUENCE:
;	 LoadSelection [, name, length, x, y, qual, dx, dy, 
;		color, lineStyle, thick, offset, overallQual, 
;		userSym, title, xTitle,  yTitle,  subtitle, text,
;		symsize ]
;-
PRO LoadSelection, name, length, x, y, qual, dx, dy,  $
	color, lineStyle, thick, offset, overallQual,  userSym, $
	title, xTitle,  yTitle,  subtitle, text, symsize
	
  COMMON Data, plotList, vectorTable
  COMMON SelectionRetrieval, plotsSelected

  IF No_Data() THEN RETURN

  nbSels = N_Selected()
  IF nbSels EQ 0 THEN RETURN

  index =  Where( plotList.name EQ plotsSelected(0) )
  indices = index(0)

  IF nbSels GT 1 THEN $
    FOR i = 1,nbSels-1 DO BEGIN
      index =  Where( plotList.name EQ plotsSelected(i) )
      indices = [ indices,  index(0) ]
    ENDFOR

  x = vectorTable( *, plotList(indices).values.x )
  y = vectorTable( *, plotList(indices).values.y )
  
  qual = vectorTable( *, plotList( indices ).qual )
  lineStyle =  vectorTable( *, plotList( indices ).lineStyle )
  userSym = vectorTable( *, plotList( indices ).userSym )
  
  idxl = plotList( indices ).errors.x.left
  idxr = plotList( indices ).errors.x.right 
  idyl = plotList( indices ).errors.y.left
  idyr = plotList( indices ).errors.y.right 
  nEls = N_Elements(vectorTable( *,0 ) )
  IF Total(idxr) EQ 0 THEN dx = vectorTable( *, idxl ) $
  ELSE BEGIN
    dx = FltArr( nEls,  nbSels, 2 )
    dx( *,*,0) = vectorTable( *, idxl )
    dx( *,*,1) = vectorTable( *, idxr )
  ENDELSE
  IF Total(idyr) EQ 0 THEN dy = vectorTable( *, idyl ) $
  ELSE BEGIN
    dy = FltArr( nEls, nbSels, 2 )
    dy( *,*,0) = vectorTable( *, idyl )
    dy( *,*,1) = vectorTable( *, idyr )
  ENDELSE

  name = plotList( indices ).name
  length = plotList( indices ).len
  color = plotList( indices ).color
  thick = plotList( indices ). thick
  offset = plotList( indices ).offset 
  title = plotList( indices ).texts.mainTitle
  xTitle = plotList( indices ).texts.title.x
  yTitle = plotList( indices ).texts.title.y
  text = plotList( indices ).texts.text
  subtitle = plotList( indices ).texts.subtitle
  overallQual = plotList( indices ).overallQual
  symsize = plotList( indices ).symsize

END ; load selection 

;+
; NAME: Remove from the Selection
; PURPOSE: Removes a plot from the selection list.
; CALLING SEQUENCE:
;	RemoveSel, name
;-
PRO RemoveSel, name

  COMMON SelectionRetrieval, plotsSelected

  idx = Where( plotsSelected EQ name )

  IF Total( idx ) EQ -1 THEN RETURN

  list = IndGen( N_Elements( plotsSelected) )
  nbToRem = N_Elements( idx )
  FOR i = 0, nbToRem-1 DO list = Where( list NE idx(i) ) 
  IF Total( list ) NE -1 THEN  plotsSelected = plotsSelected( list ) $
  ELSE plotsSelected = ''

END ; remove selection

;+
; NAME: Select All
; PURPOSE: Selects all the plots from the plot table.
; CALLING SEQUENCE:
;	SelectAll
;-
PRO SelectAll

  COMMON SelectionRetrieval, plotsSelected
  COMMON Data, plotList, dummy

  nbElems = N_Elements(plotList)
  plotsSelected = plotList(1:nbElems-1).name

END ; select all


PRO SelectFirst

  COMMON SelectionRetrieval, plotsSelected
  COMMON Data, plotList, dummmy

  plotsSelected = ['', plotList(1).name]

END ; select first

;+
; NAME: Selection
; PURPOSE: Returns the names of a subset of selected plot.
; CALLING SEQUENCE:
;	result = Selection( indexList )
;-
FUNCTION Selection, idxArr

  COMMON SelectionRetrieval, plotsSelected

  IF N_Elements(plotsSelected) EQ 0 THEN BEGIN
    Print,' No plots selected ... '
    RETURN, ''
  ENDIF

  IF N_Elements( plotsSelected ) LT Max( idxArr )+1 THEN BEGIN
    Error, 11, 'Selection'
    RETURN, ''
  ENDIF

  RETURN, plotsSelected( idxArr )

END ; selection

;+
; NAME: Initialize Selection
; PURPOSE: Initializes or resets the selection
; CALLING SEQUENCE:
;	InitSel
;-
PRO InitSel
  
  COMMON SelectionRetrieval, plotsSelected

  plotsSelected = ''

END ; init selection


PRO Init_Data ; Main Procedure


  COMMON Data, plotList, vectorTable

  leftRight = { lrStruct, left: 0, right: 0 }
  usrTextStruct = { usrTextType,  	$
	pos: {CoordReal, x: 0.0, y: 0.0 }, 	$
	text: '', 		$
	size : 0.0 }

  textStruct = { textType, 	$
	mainTitle: '', subTitle: '',	$
	title: { Labels, x: '', y: '' },	$
	text: '' }

  plotList = { plotType, 		$
	name: '', 		$
	values: { EntriesNr, x: 0, y: 0 }, $
	qual: 0,  overallQual: 0, userSym: 0,	$
	errors: { ErrStruct, x: {lrStruct}, y: {lrStruct} }, $
	texts:  textStruct,  	$
	len: 0L, 		$
	color: 255B, 	$
	lineStyle: 0, 	$
	thick: 0.0 , 		$
	offset: 0.0D,	$
	symsize: 0.0}

  vectorTable = 0
  InitSel
  Init_Defaults

END