
#include "x/Version.h"
#include "x/scolplugin.h"
#include "osversion.h"

#define CHECK(m)			if ((tmp_res=m)) return tmp_res
#define MTOI(mot)			((mot)>>1)
#define MTOP(mot)			((mot)>>1)
#define ITOM(mot)			((mot)<<1)
#define PTOM(mot)			(((mot)<<1)+1)

// static value corresponding to the os information
osinfo theOsInfo;


// set osinfo
osinfo SetOsInfo(osinfo ver)
{
    theOsInfo = ver;
	return theOsInfo;
}

// retrieve OsInfo
osinfo GetOsInfo()
{
    
#if VERSIONPC
    
    OSVERSIONINFO stOSVI ;
    DWORD vID, minV, majV;
    
    if (theOsInfo!=kOsInfoUnknown)
        return theOsInfo;
    

    memset ( &stOSVI , 0 , sizeof ( OSVERSIONINFO ) );
    stOSVI.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO );
    if (!GetVersionEx(&stOSVI))
        return SetOsInfo(kOsInfoWinUnknown);
    
    vID  = stOSVI.dwPlatformId;
    minV = stOSVI.dwMinorVersion;
    majV = stOSVI.dwMajorVersion;
    
    
    if (vID == VER_PLATFORM_WIN32_WINDOWS)
    {
        if ((majV == 4) && (minV == 0))
            return SetOsInfo (kOsInfoWin95);
        
        if ((majV == 4) && (minV == 10))
            return SetOsInfo (kOsInfoWin98);
        
        if ((majV == 4) && (minV == 90))
            return SetOsInfo (kOsInfoWinMe);
    }
    else
        if (vID == VER_PLATFORM_WIN32_NT)
        {
            if ((majV == 4) && (minV == 0))
                return SetOsInfo (kOsInfoWinNT4);
            
            if ((majV == 5) && (minV == 0))
                return SetOsInfo (kOsInfoWin2000);
            
            if ((majV == 5) && (minV == 1))
                return SetOsInfo (kOsInfoWinXp);
        }
    return SetOsInfo(kOsInfoWinUnknown);

#else

    return SetOsInfo (kOsInfoUnknown);

#endif        

/*
    
#elif
        return SetOsInfo (kOsInfoUnix);
#elif
        return SetOsInfo (kOsInfoMac);
#else
        
#endif
*/

}

// scol function retrieving 
// osinfo
int _GETosVersion(mmachine m)
{
    return MMpush(m,ITOM(GetOsInfo()));
}


#define NOSINFOPKG 11

char* osinfoname[NOSINFOPKG]=
{
    "_GETosVersion",
    "OS_UNKNOWN",
    "OS_WIN95",
    "OS_WIN98",
    "OS_WINMe",
    "OS_WINNT4",
    "OS_WIN2000",
    "OS_WINXp",
    "OS_WINUNKNOWN",
    "OS_MAC",
    "OS_UNIX"
};

#define constante(val) (int (__cdecl *)(struct Mmachine *)) ((val)<<1)

int (*osinfofun[NOSINFOPKG])(mmachine m)=
{
    _GETosVersion,
    constante(kOsInfoUnknown),
    constante(kOsInfoWin95),
    constante(kOsInfoWin98),
    constante(kOsInfoWinMe),
    constante(kOsInfoWinNT4),
    constante(kOsInfoWin2000),
    constante(kOsInfoWinXp),
    constante(kOsInfoWinUnknown),
    constante(kOsInfoMac),
    constante(kOsInfoUnix)
};


int osinfonarg[NOSINFOPKG]=
{
    0,
    TYPVAR,
    TYPVAR,
    TYPVAR,
    TYPVAR,
    TYPVAR,
    TYPVAR,
    TYPVAR,
    TYPVAR,
    TYPVAR,
    TYPVAR
};
char* osinfotype[NOSINFOPKG]=
{
    "fun [] I",
    "I",
    "I",
    "I",
    "I",
    "I",
    "I",
    "I",
    "I",
    "I",
    "I"
};


// init scol machine
int SCOLloadOsVersion(mmachine m)
{
    int k;
    if (k=PKhardpak(m,"osversion.pkg",NOSINFOPKG,osinfoname,osinfofun
		,osinfonarg,osinfotype)) 
        return k;
    return 0;
}