// plugindll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "plugindll.h"

#include <stdlib.h>

PLCallBack m_pCallback = NULL;
HWND m_hWnd = NULL;

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    // we don't care about this one
    return TRUE;
}

// make calling the script simpler by defining HELPER functions using the m_pCallback

int CALLSCRIPT(char* sName, int nParam1=0, int nParam2 = 0, int nParam3 =0, int nParam4 = 0 );
int CALLSCRIPT2(char* sName, int nParam1=0, char* chParam2 = NULL, int nParam3 =0, int nParam4 = 0 );

// the most common case all params are integers, return integer
int CALLSCRIPT(char* sName, int nParam1, int nParam2, int nParam3, int nParam4 )
{
    _PLVariable param1;
    param1.m_nVariableType = typeVariableInt;
    param1.m_nValue = nParam1;
    param1.m_sValue = NULL;
    
    _PLVariable param2;
    param2.m_nVariableType = typeVariableInt;
    param2.m_nValue = nParam2;
    param2.m_sValue = NULL;

    _PLVariable param3;
    param3.m_nVariableType = typeVariableInt;
    param3.m_nValue = nParam3;
    param3.m_sValue = NULL;

    _PLVariable param4;
    param4.m_nVariableType = typeVariableInt;
    param4.m_nValue = nParam4;
    param4.m_sValue = NULL;


    _PLVariable ParamResult;

    m_pCallback(sName,&ParamResult,¶m1,¶m2,¶m3,¶m4);

    return ParamResult.m_nValue;

}

// another version, second param is char
int CALLSCRIPT2(char* sName, int nParam1, char* chParam2, int nParam3, int nParam4 )
{
    _PLVariable param1;
    param1.m_nVariableType = typeVariableInt;
    param1.m_nValue = nParam1;
    param1.m_sValue = NULL;

    _PLVariable param2;
    param2.m_nVariableType = typeVariableString;
    param2.m_nValue = 0;
    strcpy(param2.m_sValue,chParam2);

    _PLVariable param3;
    param3.m_nVariableType = typeVariableInt;
    param3.m_nValue = nParam3;
    param3.m_sValue = NULL;

    _PLVariable param4;
    param4.m_nVariableType = typeVariableInt;
    param4.m_nValue = nParam4;
    param4.m_sValue = NULL;


    _PLVariable ParamResult;

    m_pCallback(sName,&ParamResult,¶m1,¶m2,¶m3,¶m4);

    return ParamResult.m_nValue;

}

// ********************************* Description of the plugin ABOUT box **************************

PLUGINDLL_API char* PL_GetAbout(void)
{
    // let the DVD-lab display the about box
    return "Test plugin, it will make colors negative";

    // or display your own About box and then return ""
    /*
     *  
        MessageBox(NULL,"Hey, this is nice plug-in","About my Plug-in",MB_OK);
        return "";

     */
}


// **************************************************************************************************
// this is the entry point
// we call all functions in DVD-lab with the PLCallBack which uses the same syntax as lab-TALK script.
// this simplify the SDK and yes, it is brilliant

PLUGINDLL_API void PL_RunScript(PLCallBack pCallback,HWND hWnd)
{

    // parameters passed from the DVD-lab
    m_hWnd = hWnd;
    m_pCallback = pCallback;
    
    // this one is a must!
    if (m_pCallback==NULL)
        return;

    RunScript();

}

void RunScript()
{

    int menu = MenuGetCurSel();
// VTS menu 1..255, VMG menu 10001..10255 

// show the current menu on top of all others
    MenuActivate(menu);


    int object= ObjectGetCurSel(menu);

    // Example: call the same function directly 
    // ****************************************************
         _PLVariable param1;
         param1.m_nVariableType = typeVariableInt;
         param1.m_nValue = menu;
         param1.m_sValue = NULL;
 
         _PLVariable ParamResult;

        m_pCallback("ObjectGetCurSel",&ParamResult,¶m1,NULL,NULL,NULL);

        int object2 = ParamResult.m_nValue;

    // *******************************************************

    if (object==0) 
    {
        MessageBox(m_hWnd,"No object Selected","Plug-in",MB_OK);
        return;
    }
    
    
    //get the image buffer from object and store it in buffer 1
    ImgGrabObject(1,menu,object); // imgNum = temporary image buffer 1,2 or 3


    int imgW = ImgGetWidth(1) ;
    int imgH = ImgGetHeight(1);


    BYTE* pBuffer = (BYTE*)ImgGetRGBABuffer(1);
    if (pBuffer==NULL)
        return;

    int y = 0;
    int x = 0;

    for (y=0; y<imgH;y++)
    {
        for (x=0;x<imgW;x++)
        {
            // get rgb values from buffer
            BYTE r = pBuffer[y*imgW*4+x*4];
            BYTE g = pBuffer[y*imgW*4+x*4+1];
            BYTE b = pBuffer[y*imgW*4+x*4+2];

            // we don't need alpha here, but anyway:
            BYTE alpha = pBuffer[y*imgW*4+x*4+3];

            // make negative
            r = 255-r;
            g = 255-g;
            b = 255-b;

            // put the value back to buffer
            pBuffer[y*imgW*4+x*4] = r;
            pBuffer[y*imgW*4+x*4+1] = g;
            pBuffer[y*imgW*4+x*4+2] = b;

        }
    }



    // put this all to the object
    ImgSetToObject(1,menu,object);

}