//---------------------------------------------------------------------------
//
// MODULE NAME:     main.cpp
//
// COPYRIGHT:       Copyright (c) 2013, GladeSoft, Inc.
//                  All Rights Reserved.
//
//                  NOTICE: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF
//                  GLADESOFT, INC., AND SHALL NOT BE REPRODUCED, COPIED
//                  IN WHOLE OR IN PART ADAPTED, MODIFIED, OR
//                  DISSEMINATED WITHOUT THE EXPRESS WRITTEN CONSENT
//                  OF GLADESOFT, INC. ANY REDISTRIBUTION OR
//                  PUBLICATION TO UNAUTHORIZED PERSONS IS STRICTLY
//                  PROHIBITED BY U.S. AND INTERNATIONAL COPYRIGHT LAW.
//
// DESCRIPTION:     Another example program using the Seminole embedded 
//                  web server.
//
// AUTHOR:          S. Conner
//
// CREATION DATE:   Feb 11, 2004
//
//---------------------------------------------------------------------------
//
// HISTORY OF CHANGE  
//
// -----+--------+------------------------------------------+------+---------
// VERS | DATE   | DESCRIPTION OF CHANGE                    | INIT | PR#
// =====+========+==========================================+======+=========
//  001 |02/11/04| File creation.                           | SPC  |
// -----+--------+------------------------------------------+------+---------
//  002 |06/12/09| Const correctness.                       | RAH  |
// -----+--------+------------------------------------------+------+---------
//---------------------------------------------------------------------------

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "seminole.h"
#include "sem_image.h"

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

class DemoImageHandler : public HttpdHandler
{
public:
  DemoImageHandler(const char *p_prefix);
  virtual ~DemoImageHandler();
  virtual bool Handle(HttpdRequest *p_req);
};

static const char  gServername[] = "localhost";
static const int   gServerport   = 8080;
static Httpd      *gpWebServer;

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

//---------------------------------------------------------------------------
//
// NAME:           DemoImageHandler::DemoImageHandler
//
// DESCRIPTION:    Construct the demo image handler.
//
// AUTHOR:         M. Grosberg
// CREATED:        May 29, 2006
// LAST MODIFIED:  N/A           BY:  N/A
//
//--------------------------------------------------------------------------
DemoImageHandler::DemoImageHandler(const char *p_prefix)
{
  mpPrefix = HttpdUtilities::SaveString(p_prefix);
}

//---------------------------------------------------------------------------
//
// NAME:           DemoImageHandler::~DemoImageHandler
//
// DESCRIPTION:    Destroy the demo image handler.
//
// AUTHOR:         M. Grosberg
// CREATED:        May 29, 2006
// LAST MODIFIED:  N/A           BY:  N/A
//
//--------------------------------------------------------------------------
DemoImageHandler::~DemoImageHandler()
{
  HttpdOpSys::Free((char *)mpPrefix);
}

//---------------------------------------------------------------------------
//
// NAME:           DemoImageHandler::Handle
//
// DESCRIPTION:    Process requests that may be directed at this handler.
//
// RETURNS:        True if the request was handled; false if further
//                 processing is necessary.
//
// AUTHOR:         M. Grosberg
// CREATED:        May 29, 2006
// LAST MODIFIED:  N/A           BY:  N/A
//
//--------------------------------------------------------------------------
bool DemoImageHandler::Handle(HttpdRequest *p_req)
{
  assert(p_req != NULL);

  if (IsMyPath(p_req))
  {
    HttpdGif87aRenderer rend;
    HttpdColor          ltgrn, dkgrn;
    HttpdColor          purple;

    long signal_data[180];

    if (rend.Create(450, 225, 8) != 0)
      goto failure;
    if (rend.Color(0, 255, 0, 0, ltgrn) != 0)
      goto failure;
    if (rend.Color(0, 128, 0, 0, dkgrn) != 0)
      goto failure;
    if (rend.Color(255, 0, 255, 0, purple) != 0)
      goto failure;

    HttpdRect  r;
    rend.Size(r);

    // Draw the background.
    rend.Pen(dkgrn);
    rend.Box(r);
    rend.Grid(r, 30, 8);

    // Calculate a sine wave.
    size_t i;
    for(i = 0; i < HTTPD_NUMELEM(signal_data); i++)
      signal_data[i] = (long )(100 * sin(i / (3.1415 * 4)));

    // Graph the data.
    rend.Pen(ltgrn);
    rend.LineGraph(r,
                   signal_data,
                   HTTPD_NUMELEM(signal_data),
                   -102,
                   102,
                   0);
 
    // Calculate a cosine wave.
    for(i = 0; i < HTTPD_NUMELEM(signal_data); i++)
      signal_data[i] = (long )(75 * cos(i / (3.1415 * 4)));

    // Graph the data.
    rend.Pen(purple);
    rend.LineGraph(r,
                   signal_data,
                   HTTPD_NUMELEM(signal_data),
                   -102,
                   102,
                   0);

    // Render the output. 
    rend.Render(p_req);
    return (true);
  }

  return (false);

failure:
  p_req->Respond(HTTPD_RESP_SRV_ERROR);
  return (true);

}

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

//---------------------------------------------------------------------------
//
// NAME:           failure
//
// DESCRIPTION:    Handle a fatal error.
//
// AUTHOR:         S. Conner
// CREATED:        Mar  6, 2004
// LAST MODIFIED:  N/A           BY:  N/A
//
//--------------------------------------------------------------------------
static void failure(const char *p_file, int line, const char *p_msg)
{
  assert(p_file != NULL);
  assert(line   >  0);
  assert(p_msg  != NULL);
  
  fprintf(stderr, "%s:%d Call to %s failed\n", p_file, line, p_msg);
  exit(EXIT_FAILURE);
}

//---------------------------------------------------------------------------
//
// NAME:           Initialize_The_Web_Server
//
// DESCRIPTION:    Start and configure Seminole.
//
// AUTHOR:         M. Grosberg
// CREATED:        May 29, 2006
// LAST MODIFIED:  N/A           BY:  N/A
//
//--------------------------------------------------------------------------
static void Initialize_The_Web_Server()
{
  //-------------------------------------------------------
  // Initialize the environment.
  //-------------------------------------------------------
  
  if (Httpd::Init() != 0)
    failure(__FILE__, __LINE__, "Httpd::Init()");
  
  //--------------------------------------------------------
  // Create the webserver instance.  This just initializes
  // the object --- it doesn't start it up.
  //--------------------------------------------------------
    
  gpWebServer = new Httpd(gServername, gServerport);
  if (gpWebServer == NULL)
    failure(__FILE__, __LINE__, "Httpd::Httpd()");

  //---------------------------------------------------------
  // Install the image handler as the root.
  //---------------------------------------------------------
  
  static DemoImageHandler hand("/");
  gpWebServer->Install(&hand);

  printf("Server started on host %s port %d\n", gServername, gServerport);
}

//---------------------------------------------------------------------------
//
// NAME:           main
//
// DESCRIPTION:    Entry point for the demo.
//
// AUTHOR:         S. Conner
// CREATED:        Mar  6, 2004
// LAST MODIFIED:  N/A           BY:  N/A
//
//--------------------------------------------------------------------------
int main(int argc, const char *const *argv)
{
  char buf[4];

  Initialize_The_Web_Server();
  gpWebServer->Start();
  
  printf("Press <ENTER> to stop.\n");
  fgets(buf, sizeof(buf), stdin);
  
#if HTTPD_INC_SHUTDOWN
  gpWebServer->Stop(HARD);
#endif

  return (EXIT_SUCCESS);
}
