/* -*- mode: c++; c-basic-offset: 3 -*-
 *
 * PANTHEON Project
 *
 * GREYC IMAGE
 * 6 Boulevard Mar�hal 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:
 * pandore@greyc.ensicaen.fr
 * http://www.greyc.ensicaen.fr/EquipeImage/Pandore/
 */

/**
 * Projet 3A : WAVEATOM transform
 * @authors
 *  Jalal Fadili
 *  Mahmoud Ghoniem 
 * @date 2007-02-11
 *
 */

/*
 * @file kf_rt.cc
 * Left Bump
 */

#include <math.h>
#include <complex>
using namespace std;
#include "complexe.h"
using namespace pandore;

#ifdef MAIN
#undef MAIN

namespace g{
#include "g.cpp"
}
#define MAIN
#else
namespace g{
#include "g.cpp"
}
 
#endif


/**
 * Function kf_lf
 * Left bump
 *
 * @param w : 1D image
 * @param n : 
 * @param type : type of tranform
 * @return a complex image
 */
Img1dC kf_lf (const Img1dsf w, float n, int type)
{
   double an, en1;

   Img1dC r(w.Props());
   for (int k=0; k<r.Width(); k++)
      r[k]=0;

   an = M_PI/2 * (n+.5F);
//    en = (int)n%2 ? -1:1;
   en1 = (int)(n+1)%2 ? -1:1;
 
   if (type == 1) // standard version
      for(int k=0; k<w.Width(); k++)
	 r[k] = exp(Complexe(0,-w[k]/2)) * ( exp(Complexe(0,-an)) * Complexe( g::g(en1*(w[k]+M_PI*(n+.5F)))) );

   else  // type == -1 ; Hilbert transformed version
      for(int k=0; k<w.Width(); k++)
 	 r[k] = Complexe(0,-1) * exp(Complexe(0,-w[k]/2)) * ( exp(Complexe(0,-an)) * Complexe( g::g(en1*(w[k]+M_PI*(n+.5F)))) );

   return r;
}

/**
 * Operator
 * only used for tests
 */
Errc LeftBump(Img2dsf& out, float n, int tp) {

   Img1dsf tmp(256);
   for(int k=0; k<256; k++)
      tmp[k] = -(2 * M_PI * k/256);

   Img1dC left(tmp.Props());
   //left = kf_lf(tmp,1.0F,tp);
   left = kf_lf(tmp,n,tp);
   
   out.New(2,tmp.Width());
   
   for(int k=0; k<256 ; k++){
      out[0][k] = real(left[k]);
      out[1][k] = imag(left[k]);
    }
 
   return SUCCESS;
}

#ifdef MAIN

/* 
 * Modify only the following constants, and the operator switches. 
 */ 
#define USAGE "USAGE : %s n type(1 or -1) [im_out|-]" 
#define PARC 2 // Number of parameters 
#define FINC 0 // Number of input images 
#define FOUTC 1 // Number of output images 
#define MASK 0 // Level of masking 

int main(int argc,char* argv[]) {
   Errc result; // The result code of the execution. 
   Pobject* mask; // The mask.
   Pobject* objin[FINC+1]; // The input objects; 
   Pobject* objs[FINC+1]; // The source objects masked by the mask. 
   Pobject* objout[FOUTC+1]; // The output object. 
   Pobject* objd[FOUTC+1]; // The result object of the execution. 
   char *parv[PARC+1]; // The input parameters. 
 
   ReadArgs(argc,argv,PARC,FINC,FOUTC,&mask, objin,objs,objout,objd,parv,USAGE,MASK); 
   
   objd[0] = new Img2dsf();
   Img2dsf* imd = (Img2dsf*) objd[0];
      
   result=LeftBump(*imd,atof(parv[0]),atoi(parv[1]));  
     
   if (result)
      WriteArgs(argc,argv,PARC,FINC,FOUTC,&mask,objin,objs,objout,objd,MASK);
   Exit(result);
   return 0;
}
#endif
