//******************************************************************************************************
//
// console.cpp
// Provides basic functionality for Wurmz! message console
//
//******************************************************************************************************

#include "allegro.h"

#ifdef _WIN32
#include "winalleg.h"
#else
#include <string.h>
#endif

#include <stdarg.h>
#include "gfx.h"

#include "ctype.h"

#include "defs.h"
#include "console.h"

char nl = '\n';

cons Console;

/* open the log file and create bitmaps */
void cons::Start()
{
   if (isServer)
      consoleFile = open("server.log", O_RDWR | O_CREAT | O_TRUNC, 666);
   else
      consoleFile = open("client.log", O_RDWR | O_CREAT | O_TRUNC, 666);
   WriteF("Starting Wurmz! (build %s)...", VERSION);
   WriteF("Using %s", allegro_id);
   WriteF("Running %s (%d.%d)%s", (os_type == OSTYPE_WIN95 ? "Windows 95" :
                         (os_type == OSTYPE_WIN98 ? "Windows 98" :
                          (os_type == OSTYPE_WINME ? "Windows Me" :
                           (os_type == OSTYPE_WINNT ? "Windows NT" :
                            (os_type == OSTYPE_WIN2000 ? "Windows 2000" :
                             (os_type == OSTYPE_WINXP ? "Windows XP" :
                              (os_type == OSTYPE_OS2 ? "OS/2" :
                               (os_type == OSTYPE_WARP ? "OS/2 Warp 3" :
                                (os_type == OSTYPE_DOSEMU ? "Linux DOSEMU" :
                                 (os_type == OSTYPE_OPENDOS ? "Caldera OpenDOS" :
                                  (os_type == OSTYPE_LINUX ? "Linux" :
                                   (os_type == OSTYPE_FREEBSD ? "FreeBSD" :
                                    (os_type == OSTYPE_UNIX ? "Unix" :
                                     (os_type == OSTYPE_BEOS ? "BeOS" :
                                      (os_type == OSTYPE_QNX ? "QNX" :
                                       (os_type == OSTYPE_MACOS ? "MacOS" :
                                        "unknown OS"
                                       )
                                      )
                                     )
                                    )
                                   )
                                  )
                                 )
                                )
                               )
                              )
                             )
                            )
                           )
                          )
                         )
                        ), os_version, os_revision, os_multitasking ? " (multitasking)" : "");
   WriteF("--------------------");
   WriteF("Console spawned...");
}

/* close the log file and free all data */
void cons::Close()
{
   WriteF("Console down...");
   WriteF("--------------------");
   if (console) destroy_bitmap(console);
   close(consoleFile);
   Console.freeText();
}

/* remove all messages from the queue */
void cons::freeText()
{
   consoleText *item;

   while (cText)
   {
      item = cText->next;
      free(cText);
      cText = item;
   }
}

/* render the text to a bitmap */
void cons::draw(BITMAP *where, int x, int y)
{
   int i;
   consoleText *item;

   if (redraw)
   {
      i = 0;
      item = cText;
      rectfill(console, 0, 0, 319, 49, 0);
      if (numViewports <= 2)
      while ((item) && (i<6))
      {
         if (item->life > gameTime)
         {
            drawText(console, item->text, 0, 44 - i*6);
            item = item->next;
            i++;
         }
      }
      redraw=0;
   }
   blit(console, where, 0, 0, x, y, 320, 50);
}

/* removes old messages from the queue */
void cons::checkObsolete()
{
   consoleText *item, *item2;
   
   item = cText;
   while (item)
   {
      if (item->life <= gameTime)
      {
         if (item->prev)
            item->prev->next = item->next;
         if (item->next)
            item->next->prev = item->prev;
         if (item == cText)
            cText = item->next;
         item2 = item->next;
         free(item);
         item = item2;
         redraw=1;
      }
      else
      {
         item = item->next;
      }
   }
}

/* add a text to the queue */
void cons::Write(char *text)
{
   consoleText *tempText;
   int i;
   if (isDedicated)
   {
      return;
   }

   tempText = (consoleText *)malloc(sizeof(consoleText));
   tempText->next = cText;
   tempText->prev = NULL;
   tempText->life = gameTime + 400;
   if (cText)
      cText->prev = tempText;

   cText = tempText;
   
   sprintf(tempText->text, text);
   write(consoleFile, tempText->text, strlen(tempText->text));
   write(consoleFile, &nl, 1);
   for (i=0; i<strlen(tempText->text); i++)
   {
      tempText->text[i] = toupper(tempText->text[i]);
   }
   redraw=1;
}

/* add a text to the queue */
void cons::WriteF(const char *fmt, ...)
{
   consoleText *tempText;
   va_list args;
   int i;

   if (isDedicated)
   {
      va_start(args, fmt);
      vprintf(fmt, args);
      va_end (args);
      return;
   }

   tempText = (consoleText *)malloc(sizeof(consoleText));
   tempText->next = cText;
   tempText->prev = NULL;
   tempText->life = gameTime + 400;
   if (cText)
      cText->prev = tempText;

   cText = tempText;
   
   va_start(args, fmt);
   vsprintf(tempText->text, fmt, args);
   va_end (args);
   write(consoleFile, tempText->text, strlen(tempText->text));
   write(consoleFile, &nl, 1);
   for (i=0; i<strlen(tempText->text); i++)
   {
      tempText->text[i] = toupper(tempText->text[i]);
   }
   redraw=1;
}

/* add a colored text to the queue */
void cons::WriteC(char *text)
{
   consoleText *tempText;
   int i;
   if (isDedicated)
   {
      return;
   }

   tempText = (consoleText *)malloc(sizeof(consoleText));
   tempText->next = cText;
   tempText->prev = NULL;
   tempText->life = gameTime + 400;
   if (cText)
      cText->prev = tempText;

   cText = tempText;
   
   sprintf(tempText->text, text);
   write(consoleFile, tempText->text, strlen(tempText->text));
   write(consoleFile, &nl, 1);
   for (i=0; i<strlen(tempText->text); i++)
   {
      tempText->text[i] = toupper(tempText->text[i]) ^ 128;
   }
   redraw=1;
}

/* add a colored text to the queue */
void cons::WriteCF(const char *fmt, ...)
{
   consoleText *tempText;
   va_list args;
   int i;

   if (isDedicated)
   {
      return;
   }

   tempText = (consoleText *)malloc(sizeof(consoleText));
   tempText->next = cText;
   tempText->prev = NULL;
   tempText->life = gameTime + 400;
   if (cText)
      cText->prev = tempText;

   cText = tempText;
   
   va_start(args, fmt);
   vsprintf(tempText->text, fmt, args);
   va_end (args);
   write(consoleFile, tempText->text, strlen(tempText->text));
   write(consoleFile, &nl, 1);
   for (i=0; i<strlen(tempText->text); i++)
   {
      tempText->text[i] = toupper(tempText->text[i]) ^ 128;
   }
   redraw=1;
}

