/* -*- c-basic-offset: 3 -*-
 * @(#)dictionary.cc		PANDORE 	2002-07-30
 *
 * PANTHEON Project
 *
 * GREYC IMAGE
 * 6 Boulevard Maréchal Juin
 * F-14050 Caen Cedex France
 *
 * This file is free software. You can use it, distribute it
 * and/or modify it. However, the entire risk to the quality
 * and performance of this program is with you.
 *
 * Please email any bugs, comments, and/or additions to this file to:
 * Regis.Clouard@greyc.ismra.fr
 * http://www.greyc.ismra.fr/~regis
 */

/*
 * (C)Jalal Fadili - 4-04-2006
 */

/* dictionary.cc -- dictionary objects: NameOfDict, par1, par2, par3
*
* (1) A dictionary is specified by four variables: 
*		NameOfDict, par1, par2, par3
*     where NameOfDict is a string, the name of the dictionary. par1-3
*     are three paramters of the dictionary; they can be numbers or vectors.
*
* (2) The implemented dictionaries have at most three parameters.
*     The unused par's can be given any value, e.g., 0.
*	o Discrete Cosine Transform
*		NameOfDict = 'DCT'
*		no parameter
*	o Discrete Sine Transform
*		NameOfDict = 'DST'
*		no parameter
*	o Periodized-Orthogonal Wavelet
*		NameOfDict = 'DWT'
*		par1 = L, coarsest level
*		par2 = qmf
*	o Undecimated A trou Wavelet transform
*		NameOfDict = 'UDWT'
*		par1 = L, coarsest level
*		par2 = qmf
*	o Isotropic Undecimated Wavelet Transform (B cubic spline)
*		NameOfDict = 'ISOUDWT'
*		par1 = L, coarsest level
*	o Local DCT IV transform (Cosine Packet at a fixed depth with the sine bell)
*		NameOfDict = 'LDCTIV'
*		par1 = window width
*	o Local DCT transform
*		NameOfDict = 'LDCT'
*		par1 = window width
*	o Local DST transform
*		NameOfDict = 'LDST'
*		par1 = window width
*	o Discrete Fast Curvelet Transform
*		NameOfDict = 'FCT'
*		par1 = scale
*		par2 = number of orientations at coarsest scale (16 is default)
*
* (3) Merging dictionaries:
*     One can merge any of the implemented dictionaries to form
*     a new mega dictionary by using dictionary.cc. 
*	e.g.
*		dictionary UDWT L  qmf.col 0 dict1.col
*		dictionary LDCT 16 0 	   0 dict1.col dict1.col
*	   
*	the merged dictionary contains both the UDWT and the LDCT transforms.
*	The dictionary is represented as a Pandore collection object.
*
*/


#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <pandore.h>
#include <collection.h>
#include "fispex_protect.h"

#define NB_ANGLES_COARSE 16 // For FCT
#define NumberOfDictionaries 10
char* AvailableDictionaries[NumberOfDictionaries] = {"DWT","UDWT","ISOUDWT","DCT","DST","LDCT","LDST","LDCTIV","DCTIV","FCT"};

Errc DictionaryCollection(Collection* & mergedict, char* transform, Float par1, Float* par2, int size, Float par3)
{
  Errc result;              // The result code of the execution.
  int i;
  Collection** newdict=new Collection*;
  Collection **tabdict, **oldict;
  
	
  	// Check if the dictionary is available.
	for(i = 0;i < NumberOfDictionaries; i++)
		if(!strcmp(transform,AvailableDictionaries[i])) break;

	if(i==NumberOfDictionaries){
		std::cerr<<"No dictionary "<<transform<<" implemented yet within the SparseRep pandore toolbox."<<std::endl;
		exit(FAILURE);
  	}
	
	newdict[0] = new Collection;
	newdict[0]->SETARRAY("NameOfDict",Char,transform,strlen(transform));
	newdict[0]->SETVALUE("PAR1",Float,par1);
	newdict[0]->SETARRAY("PAR2",Float,par2,size);
	newdict[0]->SETVALUE("PAR3",Float,par3);
	
	// Check existence of the collection.
	if(!mergedict){
		mergedict=new Collection;
		mergedict->SETPARRAY("Dict",Collection,newdict,1);
		result=SUCCESS;
		goto end;
	}
	
	else{	
		// Otherwise, load old dictionary and merge the new one.
		Long nbofdict=mergedict->GETPARRAYSIZE("Dict",Collection);
		oldict=mergedict->GETPARRAY("Dict",Collection);
		tabdict = new Collection*[nbofdict+1];
		
		// Copy the old dictionary.
		for(i=0;i<nbofdict;i++)
			tabdict[i]=oldict[i];
		
		// Add the last one.	
		tabdict[i]=*newdict;

		// Save the new dictionary.
		mergedict=new Collection;
		mergedict->SETPARRAY("Dict",Collection,tabdict,nbofdict+1);
		result=SUCCESS;
	}
	

end:
#ifdef DEBUG
  //We display the dictionary.
  Dictionary Dict(*mergedict);
  std::cout<<Dict.GetNbTransforms()<<" dictionaries:"<<std::endl<<Dict;
#endif
  return result;
}



