////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// mdanks@cybermed.ucsd.edu
//
// 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 "TextBase.h"

#include <stdio.h>
#include <string.h>

char *TextBase::DEFAULT_FONT = "arial.ttf";

/////////////////////////////////////////////////////////
//
// TextBase
//
/////////////////////////////////////////////////////////
// Constructor
//
/////////////////////////////////////////////////////////
TextBase :: TextBase(int argc, t_atom *argv)
		  : m_valid(0), m_theString(NULL), m_fontSize(20), m_precision(1.f),
			m_widthJus(CENTER), m_heightJus(MIDDLE)
{
    m_theString = strdup("gem");

	// do we have a text message?
	if (argc) textMess(argc, argv);

    m_inlet = inlet_new(this->x_obj, &this->x_obj->ob_pd, gensym("float"), gensym("ft1"));
}

/////////////////////////////////////////////////////////
// Destructor
//
/////////////////////////////////////////////////////////
TextBase :: ~TextBase()
{
    inlet_free(m_inlet);
    delete [] m_theString;
}

/////////////////////////////////////////////////////////
// setJustification
//
/////////////////////////////////////////////////////////
void TextBase :: setJustification(JustifyWidth wType, JustifyHeight hType)
{
	m_widthJus = wType;
	m_heightJus = hType;
}

/////////////////////////////////////////////////////////
// textMess
//
/////////////////////////////////////////////////////////
void TextBase :: textMess(int argc, t_atom *argv)
{
    delete [] m_theString;
    
    if ( argc < 1 )
    {
    	m_theString = strdup("");
    	return;
    }
    
    if (argv[0].a_type != A_SYMBOL)
    {
        post("GEM: TextBase: wrong type");
        return;
    }
    
    m_theString = strdup(argv[0].a_w.w_symbol->s_name);
    
    for (int i = 1; i < argc; i++)
    {
    	char *newtext = new char[16];
    	
        if (argv[i].a_type == A_FLOAT)
        {
            sprintf(newtext, "%f", argv[i].a_w.w_float);
        }
        else if (argv[i].a_type == A_INT)
        {
            sprintf(newtext, "%d", argv[i].a_w.w_int);
        }
        else if (argv[i].a_type == A_SYMBOL)
        {
            delete [] newtext;
            newtext = strdup(argv[i].a_w.w_symbol->s_name);
        }
        
        // hold the current string
        char *curStr = m_theString;
        
        // allocate the new memory
        m_theString = new char[(strlen(curStr) + strlen(newtext) + 2)];
        strcat(m_theString, curStr);
        strcat(m_theString, " ");
        strcat(m_theString, newtext);
        delete [] newtext;
        delete [] curStr;
    }
    setModified();
}

/////////////////////////////////////////////////////////
// static member function
//
/////////////////////////////////////////////////////////
void TextBase :: obj_setupCallback(t_class *classPtr)
{
    class_addmethod(classPtr, (t_method)&TextBase::textMessCallback,
    	    gensym("text"), A_GIMME, A_NULL);
    class_addmethod(classPtr, (t_method)&TextBase::precisionMessCallback,
    	    gensym("precision"), A_FLOAT, A_NULL);
    class_addmethod(classPtr, (t_method)&TextBase::fontNameMessCallback,
    	    gensym("font"), A_SYMBOL, A_NULL);
    class_addmethod(classPtr, (t_method)&TextBase::justifyMessCallback,
    	    gensym("justify"), A_SYMBOL, A_SYMBOL, A_NULL);
    class_addmethod(classPtr, (t_method)&TextBase::fontSizeMessCallback,
    	    gensym("ft1"), A_FLOAT, A_NULL);
    class_addlist(classPtr, (t_method)&TextBase::textMessCallback);
}
void TextBase :: textMessCallback(void *data, t_symbol *, int argc, t_atom *argv)
{
    GetMyClass(data)->textMess(argc, argv);
}
void TextBase :: fontNameMessCallback(void *data, t_symbol *s)
{
    GetMyClass(data)->fontNameMess(s->s_name);
}
void TextBase :: justifyMessCallback(void *data, t_symbol *width, t_symbol *height)
{
	JustifyWidth wType;
	if ( !strcmp(width->s_name, "left") ) wType = LEFT;
	else if ( !strcmp(width->s_name, "right") ) wType = RIGHT;
	else if ( !strcmp(width->s_name, "center") ) wType = CENTER;
	else
	{
		error("GEM: TextBase: invalid width justification: %s", width->s_name);
		return;
	}

	JustifyHeight hType;
	if ( !strcmp(height->s_name, "bottom") ) hType = BOTTOM;
	else if ( !strcmp(height->s_name, "top") ) hType = TOP;
	else if ( !strcmp(height->s_name, "center") ) hType = MIDDLE;
	else
	{
		error("GEM: TextBase: invalid height justification: %s", height->s_name);
		return;
	}

    GetMyClass(data)->setJustification(wType, hType);
}
void TextBase :: fontSizeMessCallback(void *data, t_floatarg size)
{
    GetMyClass(data)->setFontSize((int)size);
}
void TextBase :: precisionMessCallback(void *data, t_floatarg prec)
{
    GetMyClass(data)->setPrecision((float)prec);
}
