/*******************************************************************************
**
** The source file for the Jahshaka animation module
** The Jahshaka Project
** Copyright (C) 2000-2005 The Jahshaka Project
** Released under the GNU General Public License
**
*******************************************************************************/

#include "effect.h"
#include "jahcreate.h"
#include <glworldlists.h>
#include <glcore.h>
#include <vector>
#include <qcheckbox.h>
#include <qlistview.h>
#include <qimage.h>
#include <qslider.h>
#include <InputLCD.h>
#include <supergrangecontrol.h>
#include <assetexchange.h>

void GLEffect::start( )
{
	// We need to ensure plugins are loaded here when in quick start mode
	if ( JahPrefs::getInstance().getQuickStart( ) )
		initializePlugins( );

    //build the user interface into the framework hooks handed down
    buildInterface(m_controls);
    buildInterfaceMenus(m_leftcontroller,m_rightcontroller);

    //set up a nodeframe for this module
	//nodeparent = parent1;

    initializeNodes(m_parent1);

    //initalize the module
    initializeObjects();

	// Update sliders to reflected selected fps
	setResolution( JahPrefs::getInstance().getJahResolution() );
}

void GLEffect::initializeObjects()
{    
    jtrace->info( "Initializing GLEffect Class");

    //make the current opengl context current
    makeCurrent();
	
    ///////////////////////////////////////////////
    //this creates the default layers

	JahLayer* jah_layer = configureLayer ( "World", false, true, false, true );
    buildLayer(jah_layer, "World", LayerCategory::LAYER, ObjectCategory::BACKDROP );

	jah_layer = configureLayer ( "FxLayer", true, true, true, true );
	buildLayer(jah_layer, "FxLayer", LayerCategory::LAYER, ObjectCategory::MESHLAYER ); 

    setActiveJahLayer( getLayerList()->at(1)->getJahLayer() );

	//setup/customize listviewitem for layer 1
	initializeListview(1,TRUE);

    //hook up menu and sliders and default tool
    objectMenu(getNumberOfLayers() - 1);
    updateSliders();

	/////////////////////////////////////////////////////
    //initialize the buffer used for effect outputimage buffering
    //configureBuffer(1); 

    //turn forceplay on here
    setForcePlay(true);

    //////////////////////////////////////////////////////
    //added for custom variables that need to be set up 
    //only the first time around
    static bool initVariables = true;
    
	if (initVariables)
        initializeVariables();

    initVariables = false;

	//////////////////////////////////////////////////////
    //set the ui tool
    noTool();

	////////////////////////////////////////////
    //use source size renders
    VideoRenderSelect->setChecked(true);
	m_render_at_image_resolution = true;

    //this is where we get the global instance of the plugin class
    jplugin = JahPluginLib::getInstance();

	//now add first layer to nodeframe
#ifdef NEWWIREUPWIDGET
	if (haswireup)
		thewireup->addNodes(getNumberOfLayers(),"Empty Layer", 
		JahBasePath + "Pixmaps/jahlayer.png");
#else
    //now add first layer to nodeframe. TODO: do image stuff in nodes code.
    thenodeframer->setAssetName( "Empty Layer" );
    QImage theimage = QImage( JahBasePath + "Pixmaps/jahlayer.png"); 
    thenodeframer->setMainImage( theimage );
    thenodeframer->addNodes(getNumberOfLayers(),"Image");
#endif

}


void GLEffect::initializeVariables(void)
{
    //this is used for the gpu effects
    // The camera distance calculation should be passed in from the GL resize
    // routine.  This is a HACK which should be fixed FIXME

    #define PI                  3.14159265358979323846
    #define VIEW_ANGLE			45.0
    #define VIEW_ANGLE_RADIANS 	((VIEW_ANGLE / 180.0) * PI)

    m_camera_distance = ((float)Y_RESOLUTION / 2.0) / tan(VIEW_ANGLE_RADIANS / 2.0);

    noiseMatrixInitialized     = FALSE;
    fireTextureInitialized     = FALSE;
    randomTextureInitialized   = FALSE;
    contrastTextureInitialized = FALSE;
}

//////////////////////////////////////////////////
// adds a new layer to the listview and to the system


void GLEffect::objectMenu(int menu)
{

    changeSelection(menu);
}

//////////////////////////////////////////
// need to fix missing command below makeTexture
//////////////////////////////////////////
///////////////////////////////////////////
///////////////////////////////////////////

void GLEffect::addClip(assetData clip)
{
    if (clip.endframe > maxFrame)
    {
        maxFrame = clip.endframe;
        updatesliderEndframe(maxFrame);
        endFrameControl->setValue(maxFrame);
    }

    JahLayer* jah_layer = getLayerList()->at(1)->thelayer;

    jah_layer->assignAsset(clip, VideoCategory::IMAGE);

    jah_layer->LoadLayerAsset(VideoCategory::IMAGE);

    jah_layer->makeTexture();
    jah_layer->setEffectsSlidersHaveChanged(true);

    if ( jah_layer->containsCpuEffects() )
    {
        *jah_layer->getCompositeQimagePtr() = jah_layer->textureData.objectImage.copy();
        *jah_layer->getCompositeQimageFlippedPtr() = 
            jah_layer->getCompositeQimagePtr()->mirror(false,true);
    }


    //set renderspace imagesize here...
    core->imagewidth  = jah_layer->getImageWidth();
    core->imageheight = jah_layer->getImageHeight();

    updateGL();
    updateSliders();

    m_sliders_have_changed = true;

    //update start and end points to the start and end points of the source clip
    updatesliderStartframe (  clip.startframe);

    if (   jah_layer->asset.theType == VideoType::MOVIE 
        || jah_layer->asset.theType == VideoType::SEQUENCE
       ) 
    {
        updatesliderEndframe(  clip.endframe);
    }

    //update the ui settings
    startFrameControl->setValue(clip.startframe);
    endFrameControl->setValue(clip.endframe);

    // Update the nodeframer view
    //  TODO: do image stuff in nodes code

#ifdef NEWWIREUPWIDGET
	if (haswireup)
		thewireup->updateNodes(0,clip);
#else
    if ( hasnodeframer )
    {
    assetExchange exchange;
    QImage theimage;
    exchange.getStreamImagePtr( clip, theimage, 0 );
    QImage imgx = theimage.smoothScale( 100, 65, QImage::ScaleMin );
    thenodeframer->setMainImage( imgx );
    thenodeframer->setAssetName( clip.filename );
    thenodeframer->rebuildNodes();
    }
#endif
}


void GLEffect::addCpuEffect()
{
    chooseNewCpuEffect( getLayerList()->at(1), AddButton );


    EffectLayer* effect_layer = NULL;

    if ( activeLayerIsAnEffect() )
    {
        effect_layer = getActiveEffectLayer();
 
#ifdef NEWWIREUPWIDGET
		if (haswireup)
			thewireup->addNodes(getNumberOfLayers(),effect_layer->effectname);  
#endif
    }
}



void GLEffect::addMeshEffect()
{
    chooseNewMeshEffect( getLayerList()->at(1),AddRTButton );

    EffectLayer* effect_layer = NULL;

    if ( activeLayerIsAnEffect() )
    {
        effect_layer = getActiveEffectLayer();
		
#ifdef NEWWIREUPWIDGET
		if (haswireup)
			thewireup->addNodes(getNumberOfLayers(),effect_layer->effectname);  
#endif
    }
}


void GLEffect::addGpuEffect()
{
    chooseNewGpuEffect( getLayerList()->at(1),AddGpuButton );

    EffectLayer* effect_layer = NULL;

    if ( activeLayerIsAnEffect() )
    {
        effect_layer = getActiveEffectLayer();
		
#ifdef NEWWIREUPWIDGET
		if (haswireup)
			thewireup->addNodes(getNumberOfLayers(),effect_layer->effectname);  
#endif
    }
}

void
GLEffect::addCpuEffectFromTopMenu()
{
    QPopupMenu* jah_control_menu_options = Globals::getJahControl()->menuOptions[EFFECTS];
    chooseNewCpuEffect( getLayerList()->at(1), jah_control_menu_options, 1, 1 );

    EffectLayer* effect_layer = NULL;

    if ( activeLayerIsAnEffect() )
    {
        effect_layer = getActiveEffectLayer();
 
#ifdef NEWWIREUPWIDGET
		if (haswireup)
			thewireup->addNodes(getNumberOfLayers(),effect_layer->effectname);  
#endif
    }
}

void 
GLEffect::addGpuEffectFromTopMenu()
{
    QPopupMenu* jah_control_menu_options = Globals::getJahControl()->menuOptions[EFFECTS];
    chooseNewGpuEffect( getLayerList()->at(1), jah_control_menu_options, 1, 1 );

    EffectLayer* effect_layer = NULL;

    if ( activeLayerIsAnEffect() )
    {
        effect_layer = getActiveEffectLayer();
		
#ifdef NEWWIREUPWIDGET
		if (haswireup)
			thewireup->addNodes(getNumberOfLayers(),effect_layer->effectname);  
#endif
    }
}


void 
GLEffect::addMeshEffectFromTopMenu()
{
    QPopupMenu* jah_control_menu_options = Globals::getJahControl()->menuOptions[EFFECTS];
    chooseNewMeshEffect( getLayerList()->at(1), jah_control_menu_options, 1, 1 );

    EffectLayer* effect_layer = NULL;

    if ( activeLayerIsAnEffect() )
    {
        effect_layer = getActiveEffectLayer();
		
#ifdef NEWWIREUPWIDGET
		if (haswireup)
			thewireup->addNodes(getNumberOfLayers(),effect_layer->effectname);  
#endif
    }
}

