////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// mark@danks.org
//
// Implementation file
//
//    Copyright (c) 1997-1998 Mark Danks.
//    For information on usage and redistribution, and for a DISCLAIMER OF ALL
//    WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
//
/////////////////////////////////////////////////////////

#include "pix_toaa.h"

CPPEXTERN_NEW(pix_toaa)

/////////////////////////////////////////////////////////
//
// pix_toaa
//
/////////////////////////////////////////////////////////
// Constructor
//
/////////////////////////////////////////////////////////
pix_toaa :: pix_toaa() :
     m_console(0),
     m_fast(0)
{ 
  struct aa_hardware_params params = aa_defparams;
  m_context = NULL;
  m_renderparams = aa_defrenderparams;
  m_renderparams.dither = AA_FLOYD_S;
  m_out = outlet_new(this->x_obj, 0);
}

/////////////////////////////////////////////////////////
// Destructor
//
/////////////////////////////////////////////////////////
pix_toaa :: ~pix_toaa()
{ }
 
/////////////////////////////////////////////////////////
// processImage
//
/////////////////////////////////////////////////////////
void pix_toaa :: processImage(imageStruct &image)
{

}

/////////////////////////////////////////////////////////
// render
//
/////////////////////////////////////////////////////////
void pix_toaa :: render(GemState *state)
{
    if (!state->image || !state->image->newimage || !m_processOnOff) {
      m_pixBlock.image.data =  aa_text(m_context);
      m_pixBlock.image.xsize = aa_scrwidth(m_context);
      m_pixBlock.image.ysize = aa_scrheight(m_context);
      m_pixBlock.newimage = state->image->newimage;

    }
    
    int i = state->image->image.xsize * state->image->image.ysize;
    unsigned char *base =state-> image->image.data;
    int count = state->image->image.ysize * state->image->image.xsize;


    if (!m_context) setupContext(state->image->image);
    if (count != 4*aa_scrwidth(m_context)* aa_scrheight(m_context)) 
	setupContext(state->image->image);

    unsigned char* aaimg = aa_image(m_context);


    while (i)
    {
      i--;
      float grey = base[chRed] * 0.3086f + base[chGreen] * 0.6094f
	+ base[chBlue] * 0.0820f;
      base += 4;
      *aaimg++ = (unsigned char)grey;
    }
    // render the image
    if (m_fast)
      aa_fastrender(m_context, 0, 0, aa_scrwidth(m_context), aa_scrheight(m_context));
    else
      aa_render(m_context, &m_renderparams, 0, 0, aa_scrwidth(m_context), aa_scrheight(m_context));


    // output

    if (m_console)
      post("%s",aa_text(m_context));

    count = aa_scrwidth(m_context)*aa_scrheight(m_context);
    state->image = &m_pixBlock;

    m_pixBlock.image.data =  aa_text(m_context);
    m_pixBlock.image.xsize = aa_scrwidth(m_context);
    m_pixBlock.image.ysize = aa_scrheight(m_context);
    m_pixBlock.newimage = state->image->newimage;
}



void pix_toaa :: setupContext(imageStruct& image) 
{
  struct aa_hardware_params params = aa_defparams;

  params.width = (image.xsize+1)>>1; 
  params.height = (image.ysize+1)>>1; 

  if (m_context) aa_close(m_context);
  m_context = aa_init(&mem_d,&params,NULL);

  post("width = %d, height = %d", params.width, params.height);
}


/////////////////////////////////////////////////////////
// static member function
//
/////////////////////////////////////////////////////////
void pix_toaa :: obj_setupCallback(t_class * classPtr)
{ 
    class_addmethod(classPtr, (t_method)&pix_toaa::invertMessCallback,
    	    gensym("invert"), A_FLOAT, A_NULL);
    class_addmethod(classPtr, (t_method)&pix_toaa::brightMessCallback,
    	    gensym("bright"), A_FLOAT, A_NULL);
    class_addmethod(classPtr, (t_method)&pix_toaa::contrastMessCallback,
    	    gensym("contrast"), A_FLOAT, A_NULL);
}

