#include "imgmag_pi.h"
// ------------------------------------------------------------------
// ------------------ Classe ImgMagObj -----------------------

/* --Methode--*/
ImgMagObj::ImgMagObj(string filename)
  :  Magick::Image()
{
  read(filename.c_str());	
}

/* --Methode--*/
ImgMagObj::ImgMagObj(const unsigned int width, const unsigned int height)
  : Magick::Image(Magick::Geometry(width, height), Magick::ColorRGB(0., 0., 0.) )
{
}  

/* --Methode--*/
ImgMagObj::ImgMagObj(PIPixRGBArray const & rgba)
  : Magick::Image(Magick::Geometry(rgba.XSize(), rgba.YSize()), Magick::ColorRGB(0., 0., 0.) )
{
  for (unsigned int i=0; i<columns(); i++) 
    for (unsigned int j=0; j<rows(); j++) {
      PIPixRGB rgb = rgba(i,j);	
      Magick::ColorRGB col((double)rgb.red/255., (double)rgb.green/255., 
                           (double)rgb.blue/255.);  
      pixelColor(i,j,col);
    }
}

/* --Methode--*/
void ImgMagObj::FillPIRGBArray(PIPixRGBArray& rgba)
{
  rgba.SetSize(XSize(), YSize());
  for (unsigned int i=0; i<columns(); i++) 
    for (unsigned int j=0; j<rows(); j++) {
      Magick::ColorRGB col = pixelColor(i,j); 
      PIPixRGB rgb;
      rgba(i,j).red = (unsigned char)(col.red()*255.); 
      rgba(i,j).green = (unsigned char)(col.green()*255.); 
      rgba(i,j).blue = (unsigned char)(col.blue()*255.); 
    }
  return;  	
}

// ------------------------------------------------------------------
// ------------------ Classe ImgMagP2DAdaptRGB -----------------------

/* --Methode--*/
ImgMagP2DAdaptRGB::ImgMagP2DAdaptRGB(Magick::Image * img, bool ad) 
      : P2DArrayAdapter(img->columns(), img->rows() )
{ 
  aDel = ad;   mPix = img; 
}

/* --Methode--*/
ImgMagP2DAdaptRGB::~ImgMagP2DAdaptRGB() 
{ 
  if ( (aDel) && (mPix) ) delete mPix; 
}

/* --Methode--*/
double ImgMagP2DAdaptRGB::Value(int ix, int jy) 
{  
  if ( (ix < 0)  || (jy < 0) || (ix >= sX) || (jy >= sY) ) return(0.); 
  Magick::ColorRGB col = mPix->pixelColor(ix,jy); 
  return ( ((col.blue()*256.+col.green())*256.+col.red())*255. );
}

/* --Methode--*/
double ImgMagP2DAdaptRGB::MeanVal(int ix1, int ix2, int jy1, int jy2)  
{
  int ec;
  if (ix1>ix2) { ec=ix1; ix1=ix2; ix2=ec; }
  if (jy1>jy2) { ec=jy1; jy1=jy2; jy2=ec; }    
  unsigned long r = 0.;
  unsigned long g = 0.;
  unsigned long b = 0.;
  Magick::ColorRGB rgb;
  for(int j=jy1; j<=jy2; j++) {
    for(int i=ix1; i<=ix2; i++)  {
      rgb = mPix->pixelColor(i, j);
      r += (unsigned long)(rgb.red()*255.);  
      g += (unsigned long)(rgb.green()*255.);   
      b += (unsigned long)(rgb.blue()*255.); 
    }
  }
  unsigned long n = (jy2-jy1+1)*(ix2-ix1+1);   
  r /= n; g /= n; b /= n;
  return ((double)((b*256+g)*256+r)); 
/*  La meme chose calculee en double ne marche pas !!!!
  double r = 0.;
  double g = 0.;
  double b = 0.;
  Magick::ColorRGB rgb;
  for(int j=jy1; j<=jy2; j++) {
    for(int i=ix1; i<=ix2; i++)  {
      rgb = mPix->pixelColor(i, j);
      r += rgb.red();  g += rgb.green();   b += rgb.blue(); 
    }
  }
  double n = (jy2-jy1+1)*(ix2-ix1+1);   
  r /= n; g /= n; b /= n;
  return ( ((b*256.+g)*256.+r)*255. );
*/
}   


// ------------------------------------------------------------------
// ------------------ Classe ImgMagP2DAdaptGS -----------------------

/* --Methode--*/
ImgMagP2DAdaptGS::ImgMagP2DAdaptGS(Magick::Image * img, bool ad) 
      : P2DArrayAdapter(img->columns(), img->rows() )
{ 
  aDel = ad;   mPix = img; 
}

/* --Methode--*/
ImgMagP2DAdaptGS::~ImgMagP2DAdaptGS() 
{ 
  if ( (aDel) && (mPix) ) delete mPix; 
}

/* --Methode--*/
double  ImgMagP2DAdaptGS::Value(int ix, int jy) 
{  
  if ( (ix < 0)  || (jy < 0) || (ix >= sX) || (jy >= sY) ) return(0.); 
  Magick::ColorGray grey = mPix->pixelColor(ix,jy); 
  return ( grey.shade() );
}

/* --Methode--*/
double  ImgMagP2DAdaptGS::MeanVal(int ix1, int ix2, int jy1, int jy2)  
{
  int ec;
  if (ix1>ix2) { ec=ix1; ix1=ix2; ix2=ec; }
  if (jy1>jy2) { ec=jy1; jy1=jy2; jy2=ec; }    
  double gr = 0;
  for(int j=jy1; j<=jy2; j++) 
    for(int i=ix1; i<=ix2; i++)  {
      Magick::ColorGray grey = mPix->pixelColor(i, j);
      gr += grey.shade();
    }
  double n = (jy2-jy1+1)*(ix2-ix1+1);   
  return ( gr/n );  
}   

// ------------------------------------------------------------------
//  Adapteur d'objet ImgMagObj pour gestion  par NamedObjMgr de piapp

/* --Methode-- */
NOMAdapter_ImgMag::NOMAdapter_ImgMag(ImgMagObj* o)
  : NObjMgrAdapter(o)
{
mImg = o;
}

/* --Methode-- */
NOMAdapter_ImgMag::~NOMAdapter_ImgMag()
{
}

/* --Methode-- */
NObjMgrAdapter* NOMAdapter_ImgMag::Clone(AnyDataObj* o)
{
ImgMagObj* img = dynamic_cast<ImgMagObj *>(o);
if (img) return ( new NOMAdapter_ImgMag(img) );
return ( new NObjMgrAdapter(o) );
}
string NOMAdapter_ImgMag::GetDataObjType()
{
  return ("ImgMagObj ");
}

/* --Methode-- */
void NOMAdapter_ImgMag::Print(ostream& os, int lev)
{
  if (mImg == NULL) return;	
  os << " ImgMagObj - File=" << mImg->fileName() << "  Width=" << mImg->columns()
     << " x Height=" << mImg->rows() << endl; 
//  if (lev > 1) 
}

/* --Methode-- */
P2DArrayAdapter* NOMAdapter_ImgMag::Get2DArray(string& dopt)
{
  if (mImg == NULL) return NULL;
  if (dopt.find("monochrome") < dopt.length()) {
    dopt = "lut=lin,0.,1.  grey128 " + dopt;
    return new ImgMagP2DAdaptGS(mImg);		
  }
  else {
    dopt = "lut=rgb  rgb32768cm " + dopt;
    return new ImgMagP2DAdaptRGB(mImg);		
  }
}

/* --Methode-- */
NTupleInterface* NOMAdapter_ImgMag::GetNTupleInterface(bool& adel)
{
  if (mImg == NULL) return NULL;	
  adel = true;
  return( new NTupInt_ImgMag(mImg) );
}


// ---- Class Interface NTuple pour ImgMagObj

/* --Methode-- */
NTupInt_ImgMag::NTupInt_ImgMag(ImgMagObj* img)
{
  mImg = img;
}

/* --Methode-- */
NTupInt_ImgMag::~NTupInt_ImgMag()
{
}

/* --Methode-- */
sa_size_t NTupInt_ImgMag::NbLines() const
{
  if (mImg)  return( mImg->XSize()*mImg->YSize() );
  else return 0;
}

/* --Methode-- */
sa_size_t NTupInt_ImgMag::NbColumns() const 
{
  return(6);
}

/* --Methode-- */
r_8* NTupInt_ImgMag::GetLineD(sa_size_t n) const 
{
  int i;
  if ((n < 0) || (n >= (int)(mImg->XSize()*mImg->YSize())  )) 
    for(i=0; i<6; i++)  mRet[i] = 0.;
else { 
  int i = n%mImg->XSize(); 
  int j = n/mImg->XSize();
  Magick::ColorRGB rgb = mImg->pixelColor(i, j);
  Magick::ColorGray grey = mImg->pixelColor(i, j);
  mRet[0] = i;  mRet[1] = j; 
  mRet[2] = rgb.red();  
  mRet[3] = rgb.green();  
  mRet[4] = rgb.blue();  
  mRet[5] = grey.shade();
  }
return(mRet);
}

/* --Methode-- */
string NTupInt_ImgMag::VarList_C(const char* nx) const 
{
string nomx;
if (nx) nomx = nx;
else nomx = "_xh_";
string vardec = "double x,y,i,j,r,g,b,I; \n";
vardec += "x = " + nomx + "[0]; i = " + nomx + "[0]; \n";
vardec += "y = " + nomx + "[1]; j = " + nomx + "[1]; \n";
vardec += "r = " + nomx + "[2];  g = " + nomx + "[3]; \n";
vardec += "b = " + nomx + "[4];  I = " + nomx + "[5]; \n";
return(vardec);
}



