/***********************************************************************************************/
/*                                                                                             */
/*          Implementation des fonctions du package active.pkg                                 */
/*                                                                                             */
/***********************************************************************************************/
//
// Modification history:
//$ FA(18/07/2001): Include baselib.h were declaration of MAXCOM was moved 
//

#include "x/scolplugin.h"
#include "x/version.h"

#include <stdio.h>
#include <string.h>

/*
#include "../kernel/include/kernel.h"
#include "winscol.h"
#include "../kernel/baselib.h"
*/

#include "x/Version.h"
#include "x/scolplugin.h"

  
#include "objstr.h"
#include "active.h"


int OBJTYPXTENSION;

/* Definition  des reflexes pour les Evenements ActiveX */
#define RFLXTENSION_NB 1
#define RFLXTENSION_EVENT 0


extern HWND ActiveXhwnd;


HWND NewWindowActiveX ( PtrObjWindow Wnd , char * Name , HWND Parent )
{    
int Style ;
//int  MDITest ;
int FF ;
int Ex_Flag = 0 ;
RECT r ;
HWND H ;
//WINDOWPLACEMENT wnd ;
char classe [255 ] ;
CLIENTCREATESTRUCT client ;

        Style = 0 ;        
        FF = Wnd->Flags ;

      FF = Wnd->Flags ;
      if (FF & WN_NOBACKGROUND)
        strcpy ( classe , "NoBackgroundClass2D" );
      else
        strcpy ( classe , "GenericClass2D" );

        if ( Parent != NULL )
        {
            if  (FF&WN_GROUP)
            {
                Style |= BS_GROUPBOX|WS_CHILD |WS_CLIPSIBLINGS;
                strcpy (classe,"button");              
            }
            else if ( FF & WN_CHILD )
            {
                Style |= (WS_CHILD | WS_CLIPSIBLINGS) ; 
                if ((FF & WN_CHILDMENU)==0) FF |= WN_NOCAPTION ;              
           
            } else Style |= WS_POPUP  ;                
        } else Style |= WS_POPUP ;
        if (( FF & WN_NOCLIPCHILDREN ) == 0 ) 
            Style |= WS_CLIPCHILDREN ;

        if (( FF & WN_GROUP ) == 0 )
        {
            if ( ( FF & WN_NOBORDER ) == 0 ) Style |= WS_BORDER ;
            if ( ( FF & WN_NOCAPTION )== 0 ) Style |= WS_CAPTION ; //SH
        }
        if ( FF & WN_MINIMIZE ) Style |= WS_MINIMIZE ;                
        if ( FF & WN_MINBOX ) Style |= WS_MINIMIZEBOX ;
        if ( FF & WN_MAXBOX ) Style |= WS_MAXIMIZEBOX ;
        if ( FF & WN_SIZEBOX ) Style |= WS_SIZEBOX|WS_MAXIMIZEBOX  ;
        if ( FF & WN_MENU ) Style |= WS_SYSMENU ;  
        if ( FF & WN_DRAGDROP ) Ex_Flag |= WS_EX_ACCEPTFILES ;
        if ( FF & WN_HSCROLL ) Style |= WS_HSCROLL ;
        if ( FF & WN_VSCROLL ) Style |= WS_VSCROLL ; 
 
        if ( FF & WN_DOWN ) Ex_Flag |= WS_EX_CLIENTEDGE ;
        
        //MDITest = 0 ;
        
        r.left=0;
	    r.top=0;
	    r.right= Wnd->TailleW;
	    r.bottom=Wnd->TailleH;
        
        AdjustWindowRect(&r,Style,FALSE);
         
        client.hWindowMenu = NULL ;
        client.idFirstChild = 1000 ;
        H = CreateWindowEx ( Ex_Flag , classe ,                /* classe de fenetre */
                        Name , Style ,                  /* nom, style */
                        Wnd->PosX , Wnd->PosY ,                /* position x,y */
                        r.right - r.left , r.bottom - r.top ,/* taille de la fenetre */
                        Parent , NULL ,                 /* parent , menu */
                        (HINSTANCE)SCgetExtra("this_inst") , ( LPSTR ) &client  ) ;            /* program inst , params */
                

        return H ;
}





/*****************************************************************************/
/*                                                                           */
/*  fonction int GETactiveXWindow ( mmachine m ) ;                           */
/*                                                                           */
/*  fonction C correspondant a la fonction magma                             */
/*                                                                           */
/*  Obj _GETactiveXWindow ( Obj parent , int PosX , int PosY , int TailleW   */
/*    int TailleH , int Flags , int MHandler , S Nom , I sock )              */
/*                                                                           */
/*  cette fonction cree une nouvelle fenetre windows                         */
/*                                                                           */
/*****************************************************************************/
HWND ActiveXhwnd=NULL;

//HWND axhwnd=NULL;

int GETactiveXWindow ( mmachine m )
{   
        
int s,l , dummy,s2 , res ;

PtrObjWindow Wnd;
PtrObjVoid O;
HWND HW , Parent ;      
char Name [ 1024 ] ;
RECT rc;


        ActiveXhwnd = (HWND)SCgetExtra("ActiveXhwnd");


        /****************************** DEBUG 2D *******************************/    
        #ifdef TRACE2D
                MMechostr (1 , "DBG _GETactiveXWindow\n") ;            
                FDebug2D ( m ) ;
        #endif
        /************************************************************************/
        if (ActiveXhwnd==NULL)
		{
			m->pp+=3;
            MMechostr(MSKDEBUG,"no activeX window\n" ) ;
			return MMpush(m,NIL);
		}
        dummy           = MMpull(m)     ;
        /* ajouter ici le test sur la taille des noms de fenetres */
        if ( dummy == NIL ) 
          strcpy ( Name , "SCOL://" ) ; 
        else
          //$BLG - v4.6a4
          //Didn't remove (SCOL) in PopUp AX Window name - this one isn't displayed
          sprintf ( Name , "(SCOL)%s" , ( char * ) MMstart(m, (dummy>>1) + 1) ) ;

        /* creation de la zone memoire pour l'objet de base */
        l = ( sizeof ( struct ObjVoid ) + 3 ) >> 2 ;        
        s = MMmallocCLR(m,l,TYPETAB) ;
        if ( s == NIL )
        {
            MMechostr(MSKDEBUG,"_create_window : Error in Alloc MAGMA memory\n" ) ;
            return MERRMEM ;
        }               
        if ( MMpush ( m,(s<<1)+1 )) return MERRMEM ;
        /* on remet s sur la pile au cas ou le malloc suivant */
        /* causerait un GC */

        /* creation de la zone memoire pour les donnees propres aux fenetres */
        l = ( sizeof ( struct ObjWindow ) + 3 ) >> 2 ;
        
        s2 = MMmalloc (m,l,TYPEBUF);
        if ( s2 == NIL )
        {
                MMechostr (1,"_create_window: Error in Alloc MAGMA MEmory\n" ) ;             
                return MERRMEM ;
        }
                
        Wnd = ( PtrObjWindow ) MMstart(m, s2 ) ;
        s = MMpull(m) ;
        O = ( PtrObjVoid ) MMstart(m, (s >> 1) ) ;

        /* initialisation de la structure fenetre */
        O -> Type             = OBJ_TYPE_WINDOW << 1  ;        
        Wnd -> Flags          = MMpull(m) >> 1 ;
//        Wnd -> TailleH        = MMpull(m) >> 1 ;
//        Wnd -> TailleW        = MMpull(m) >> 1 ;
//        Wnd -> PosY           = MMpull(m) ;
//        Wnd -> PosX           = MMpull(m) ;
//        if ( Wnd->PosX == NIL ) Wnd->PosX = CW_USEDEFAULT ; else Wnd->PosX >>= 1 ;
//        if ( Wnd->PosY == NIL ) Wnd->PosY = CW_USEDEFAULT ; else Wnd->PosY >>= 1 ;
//        O -> Father           = MMpull(m) ;
        Wnd -> Flags          = WN_CHILD | WN_ACTIVEX ;
        GetClientRect(ActiveXhwnd,&rc);
        Wnd -> TailleH        = rc.bottom;
        Wnd -> TailleW        = rc.right;
        Wnd -> PosY           = -1;
        Wnd -> PosX           = -1;
        Wnd -> Cursor         = NULL ;
        O -> Father           = NIL ;
        
        O -> Tab              = NIL ;
        O->Buffer = ( s2 << 1 ) + 1 ;
         
        /* recuperation du handler window du parent, si parent il y a */
#if 0
        if ( O -> Father == NIL ) Parent = NULL ;
        else
        {
                OP = ( PtrObjVoid ) MMstart(m, (O->Father>>1) ) ;
                /* verifie que le pere est bien de type Fenetre */                          
                PW = ( PtrObjWindow ) MMstart(m,(OP->Buffer >> 1)) ;
                Parent = PW->WHandler ;
        }
#endif
        

        Parent=ActiveXhwnd;
        /* creation de la ressource */
        HW = NewWindowActiveX ( Wnd , Name , Parent ) ;
        if ( ! HW )
        {

            MMechostr (1,"_GETactiveXWindow : Error in creating the WIN95 Object - Check the values\n" ) ;
            MMset(m,0,NIL) ;
            return 0 ;
        }
        Wnd->WHandler = HW  ;           
        
        /* affichage de la fenetre */
        if ( Wnd->Flags & WN_HIDE ) ShowWindow ( HW , SW_HIDE ) ; 
        else if ( Wnd->Flags & WN_MINIMIZE )ShowWindow ( HW , SW_MINIMIZE ) ;
        else ShowWindow( HW , SW_SHOW) ;
        UpdateWindow( HW );

        MMpush(m,s) ;
        MMechostr(MSKDEBUG,"activeX window %x (%x)ok\n",(int)HW,MMget(m,1)>>1) ;
        res = OBJcreate(m,OBJtypebyname("OBJTYPWINDOW"),(int)HW,-1,1);/*OBJTYPWINDOW,(int)Parent) ;*/
      
        /******************************** DEBUG 2D ********************************/
        #ifdef TRACE2D
                FDebug2D ( m ) ;
                MMechostr ( 1 , "DBG _GETactiveXWindow done : WH = %d \n" , HW ) ;
        #endif
        /***************************************************************************/
        return res ;           
}

/*
__declspec (dllexport) char* AXExtract(char *comm,int n)
{
  static char buf[MAXCOM+1];
  char* mots[128];
  int  nbmots;

  if (n<0) return NULL;
  strcpy(buf,comm);

  nbmots=Mcutting(buf,mots);
  if (n>nbmots) return NULL;

  return mots[n];
}

__declspec (dllexport) int AXExtractNWords(char *comm)
{
  char buf[MAXCOM+1];
  char* mots[128];
  int  nbmots;

  if (!comm) return 0;
  strcpy(buf,comm);

  nbmots=Mcutting(buf,mots);
  return nbmots;
}

void (*AXfun) (mmachine m,UINT wParam, LONG lParam)=NULL;
void (*AXdestroy) (mmachine m,long lParam)=NULL;


//__declspec (dllexport) int AXGetEnv (HWND** wnd,void (*f)(long))
//{
//  if (wnd) 
//    *wnd=hscol;
//  AXfun=f;

//  return 0;
//}

typedef struct FData
{
  char *sFName;
  char *sFHelp;
  char **sPName;
  DISPID lDispID;
  int nNumParams;
  VARTYPE *pPTypes;
  VARTYPE nRType;
  BOOL nPtr;
  void *pNext;
  INVOKEKIND invKind;
}FData; 

typedef struct paramreflex 
{
  void * dispatch;
  FData * Event;
  DISPID dispid;
  REFIID refiid;
  DISPPARAMS *dispparams;
  VARIANT * result;
} paramreflex;


int XTensionEventScol(mmachine m,HWND hwnd,unsigned msg,UINT wParam, LONG lParam,int *ret)
{
  if (lParam) 
  {
    paramreflex* p=(paramreflex*)lParam;
    if (AXfun)
      (AXfun)(m,wParam,lParam);
//    free (p);
  }
  else 
    MMechostr(MSKDEBUG,"Active Event without structure !\n");
  return 0;
}

int XTensionDestroy (mmachine m,int handsys,int objm)
{
  (AXdestroy)(m,handsys);
  return 0;
}

int XTini(mmachine m)
{
	OBJTYPXTENSION=OBJregister(RFLXTENSION_NB,0,XTensionDestroy,"OBJTYPXTENSION");
//	WM_XTENSION=OBJgetUserEvent();
	OBJdefEvent(WM_XTENSION,XTensionEventScol);
	return 0;
}

*/

#define NACTIVEXPKG 1

char* activexname[NACTIVEXPKG]=
{"_GETactiveXWindow"};

int (*activexfun[NACTIVEXPKG]) (mmachine m)=
{GETactiveXWindow};

int activexnarg[NACTIVEXPKG]=
{3};

char* activextype[NACTIVEXPKG]=
{"fun [Chn I S] ObjWin"};




int SCOLloadActiveX(mmachine m)
{
    return PKhardpak(m,"ACTIVEX.pkg",NACTIVEXPKG,activexname,activexfun
		,activexnarg,activextype);
}