#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
//#include <sys/ipc.h>
//#include <sys/shm.h>
#include <sys/stat.h>
#include <string.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <errno.h>

// FIXME TTimo should we gard this? most *nix system should comply?
#include <termios.h>

#include "../game/q_shared.h"
#include "../qcommon/qcommon.h"
#include "../renderer/tr_public.h"

#include "linux_local.h" // bk001204

unsigned  sys_frame_time;

uid_t saved_euid;
qboolean stdin_active = qtrue;

// =============================================================
// tty console variables
// =============================================================

// enable/disabled tty input mode
// NOTE TTimo this is used during startup, cannot be changed during run
static cvar_t *ttycon = NULL;
// general flag to tell about tty console mode
static qboolean ttycon_on = qfalse;
// when printing general stuff to stdout stderr (Sys_Printf)
//   we need to disable the tty console stuff
// this increments so we can recursively disable
static int ttycon_hide = 0;
// some key codes that the terminal may be using
// TTimo NOTE: I'm not sure how relevant this is
static int tty_erase;
//static int tty_eof;

static struct termios tty_tc;

static field_t tty_con;

// history
// NOTE TTimo this is a bit duplicate of the graphical console history
//   but it's safer and faster to write our own here
#define TTY_HISTORY 32
static field_t ttyEditLines[TTY_HISTORY];
static int hist_current = -1, hist_count = 0;

// =======================================================================
// General routines
// =======================================================================

// bk001207 
#define MEM_THRESHOLD 96*1024*1024

//
//==================
//Sys_LowPhysicalMemory()
//==================
//
qboolean Sys_LowPhysicalMemory() {return qfalse;}

//
//==================
//Sys_FunctionCmp
//==================
//
int Sys_FunctionCmp(void *f1, void *f2) {return qtrue;}

//
//==================
//Sys_FunctionCheckSum
//==================
//
int Sys_FunctionCheckSum(void *f1) { return 0;}

//
//==================
//Sys_MonkeyShouldBeSpanked
//==================
//
int Sys_MonkeyShouldBeSpanked( void ) { return 0;}
void Sys_BeginProfiling( void ){}

//
//=================
//Sys_In_Restart_f
//
//Restart the input subsystem
//=================
//
void Sys_In_Restart_f( void ) 
{
  IN_Shutdown();
  IN_Init();
}

// =============================================================
// tty console routines
// NOTE: if the user is editing a line when something gets printed to the early console then it won't look good
//   so we provide tty_Clear and tty_Show to be called before and after a stdout or stderr output
// =============================================================

void tty_FlushIn(){}
void tty_Back(){}
void tty_Hide(){}
void tty_Show(){}
void Sys_ConsoleInputShutdown(){}
void Hist_Add(field_t *field){}

field_t *Hist_Prev()
{
  field_t* tmp;
  return tmp;
}

field_t *Hist_Next()
{
  field_t* tmp;
  return tmp;
}

// =============================================================
// general sys routines
// =============================================================

void Sys_Exit( int ex ) {}


void Sys_Quit (void) {}

void Sys_Init(void){}

void  Sys_Error( const char *error, ...){}
void Sys_Warn (char *warning, ...){}
int Sys_FileTime (char *path){return -1;}
void floating_point_exception_handler(int whatever){}
void Sys_ConsoleInputInit(){}
char *Sys_ConsoleInput(void)
{
  char text[256];
  return text;
}

//_____________________________________________________________________________/

void Sys_UnloadDll( void *dllHandle ){}
extern char   *FS_BuildOSPath( const char *base, const char *game, const char *qpath );
void *Sys_LoadDll( const char *name, char *fqpath ,
                   int (**entryPoint)(int, ...),
                   int (*systemcalls)(int, ...) ) 
{}

//
//========================================================================
//
//BACKGROUND FILE STREAMING
//
//========================================================================
//

void Sys_InitStreamThread( void ) {}
void Sys_ShutdownStreamThread( void ) {}
void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) {}
void Sys_EndStreamedFile( fileHandle_t f ) {}

int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
  return 0;//FS_Read( buffer, size * count, f );
}

void Sys_StreamSeek( fileHandle_t f, int offset, int origin ){}

//
//========================================================================
//
//EVENT LOOP
//
//========================================================================
//

// bk000306: upped this from 64
#define	MAX_QUED_EVENTS		256
#define	MASK_QUED_EVENTS	( MAX_QUED_EVENTS - 1 )

sysEvent_t  eventQue[MAX_QUED_EVENTS];
// bk000306: initialize
int   eventHead = 0;
int             eventTail = 0;
byte    sys_packetReceived[MAX_MSGLEN];

//
//================
//Sys_QueEvent
//
//A time of 0 will get the current time
//Ptr should either be null, or point to a block of data that can
//be freed by the game later.
//================
//
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {}

//
//================
//Sys_GetEvent
//
//================
//
sysEvent_t Sys_GetEvent( void ) {
  sysEvent_t  ev;
  return ev;
}

//_____________________________________________________________________________/
  
qboolean Sys_CheckCD( void ) {return qtrue;}
void Sys_AppActivate (void){}
char *Sys_GetClipboardData(void) {return NULL;}
void  Sys_Print( const char *msg ){}
void    Sys_ConfigureFPU() {}
void Sys_PrintBinVersion( const char* name ) {}
void Sys_ParseArgs( int argc, char* argv[] ) {}

#include "../client/client.h"
extern clientStatic_t cls;

int zmain ( int argc, char* argv[] ){}
/*
{
  // int 	oldtime, newtime; // bk001204 - unused
  int   len, i;
  char  *cmdline;
  void Sys_SetDefaultCDPath(const char *path);

  // go back to real user for config loads
  saved_euid = geteuid();
//  seteuid(getuid());

  Sys_ParseArgs( argc, argv );  // bk010104 - added this for support

  Sys_SetDefaultCDPath(argv[0]);

  // merge the command line, this is kinda silly
  for (len = 1, i = 1; i < argc; i++)
    len += strlen(argv[i]) + 1;
  cmdline = malloc(len);
  *cmdline = 0;
  for (i = 1; i < argc; i++)
  {
    if (i > 1)
      strcat(cmdline, " ");
    strcat(cmdline, argv[i]);
  }

  // bk000306 - clear queues
  memset( &eventQue[0], 0, MAX_QUED_EVENTS*sizeof(sysEvent_t) ); 
  memset( &sys_packetReceived[0], 0, MAX_MSGLEN*sizeof(byte) );

  Com_Init(cmdline);
  NET_Init();

  Sys_ConsoleInputInit();

//  fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
	
#ifdef DEDICATED
	// init here for dedicated, as we don't have GLimp_Init
	InitSig();
#endif

  while (1)
  {
#ifdef __linux__
    Sys_ConfigureFPU();
#endif
    Com_Frame ();
  }
}
*/
///


#include <menuet/os.h>

#define WinSizeX 2
#define WinSizeY 2
int winwidth, winheight;

void paint(void) // +
{
	__menuet__window_redraw(1);
	winwidth=256*WinSizeX+8;
	winheight=240*WinSizeY+55;
	__menuet__define_window(100,100,winwidth,winheight,0x03000000,0x800000FF,0x000080);
	//__menuet__bar(5,40,winwidth-10,winheight-55,0);
	//__kolibri__draw_title(Title);
	__menuet__window_redraw(2);
}

int ProcessEvent(int event)
{
	char key=0;
        switch(event)
	{
		case 1:
			paint();
		break;
		case 2:
			key=__menuet__getkey();
		break;
		case 3:	
			if(__menuet__get_button_id()==1) 
			{
				//DriverInterface(DES_EXIT,0);
				__menuet__sys_exit();
			}
		break;
	}
  return key;
}


extern char __menuet__app_param_area[1024];

int app_main(int argc, char** argv)
{ 
  char key;
  int i;

  paint();
  for(;;)
  {	i =__menuet__wait_for_event();
	//if (i==2) break;
	key=ProcessEvent(i);
        if (key==27 || key==1) break;
  }

  //zmain(argc, argv);
  return 1;
}
