/*

                                   _JNJ`                        
                               .JNMH`                           
                              JMMF`       `;.                   
                            .NMM)          `MN.                 
                            MMM)            (MML                
                           (MMM`             MMML               
                     M  I  D  N  I  G  H  T    C  o  D  E       
                           (NMMF             MHNH               
                            NMML            .MMM                
                             NMML          .NMH                 
                              4MMNL       .#F                   
                               `4HNNL_   `                      
                                   `"""`                        

                          Copyright (C) 2004-2005
       "Ian (Larry) Latter" <ian dot latter at midnightcode dot org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, and mirrored at the Midnight Code web
    site; as at version 2 of the License only.
  
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
  
    You should have received a copy of the GNU General Public License
    (version 2) along with this program; if not, write to the Free
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA, or see http://midnightcode.org/gplv2.txt

*/

/* main.c :: Midnight Code library test and example program		*/


#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>


#include "libmidnightcode/libmidnightcode.h"


int
main(int argc, char **argv) {
  int ret_i;
  int showBroadcast = 1;
  int vartwo = 4;
  int help = 0;
  int list_silent = 0;
  float varthr = 1.2;
  char info[64] = "\0";
  struct in_addr ip_addr;
  struct in_addr host;;
  int n;

  struct entry_struct_name {
    int test_val;
    midnightcode_list_entry(entry_struct_name);
  };

  struct entry_struct_name *np, *op;

  struct midnightcode_switch_t switches[] = {
    { "b", "broadcast", "Example integer value",
      MIDNIGHTCODE_SWITCH_TYPE_INT, 0, 0, &showBroadcast },
    { "v", "var2", "Another example integer value",
      MIDNIGHTCODE_SWITCH_TYPE_INT, 0, 0, &vartwo },
    { "v3", "var3", "A float test value",
      MIDNIGHTCODE_SWITCH_TYPE_FLOAT, 0, 0, &varthr },
    { "i", "info", "An example string value",
      MIDNIGHTCODE_SWITCH_TYPE_STRING, 64, 0, &info },
    { "ho", "host", "A host example that returns an IP",
      MIDNIGHTCODE_SWITCH_TYPE_HOST, 0, 0, &host.s_addr },
    { "ip", "ipaddr", "An IP example that only accepts an IP",
      MIDNIGHTCODE_SWITCH_TYPE_IP, 0, 0, &ip_addr.s_addr },
    { "l", "list_silent", "On/Off - Silent list render",
      MIDNIGHTCODE_SWITCH_TYPE_NONE, 0, 0, &list_silent },
    { "h", "help", "Display this help/usage screen",
      MIDNIGHTCODE_SWITCH_TYPE_NONE, 0, 0, &help },
    { 0 }
  };

  memset(&ip_addr, 0, sizeof(struct in_addr));
  memset(&host, 0, sizeof(struct in_addr));
  if((ret_i = midnightcode_switch_process(argc, argv, switches)) != 0) {
    fprintf(stdout, "\n");
    midnightcode_logo(0,
      MIDNIGHTCODE_LICENSE_STYLE_BLOOD_MOON);
    midnightcode_license(0,
      MIDNIGHTCODE_LICENSE_STYLE_BLOOD_MOON, 
      MIDNIGHTCODE_LICENSE_TEXT_COPYRIGHT);
    fprintf(stdout, "    Error in switches, switch \"%s\" is unkown"
            " at parameter number %d.\n\n", argv[ret_i], ret_i);
    midnightcode_switch_usage(MIDNIGHTCODE_SWITCH_STYLE_SOFT,
                              argv[0], switches);
    exit(1);
  }
  if(help) {
    midnightcode_logo(0,
      MIDNIGHTCODE_LICENSE_STYLE_BLOOD_MOON);
  midnightcode_license(0,
    MIDNIGHTCODE_LICENSE_STYLE_BLOOD_MOON, 
    MIDNIGHTCODE_LICENSE_TEXT_COPYRIGHT);
    midnightcode_switch_usage(MIDNIGHTCODE_SWITCH_STYLE_SOFT,
                              argv[0], switches);
    exit(1);
  }

  /*
  fprintf(stdout, "--broadcast=[%d]\n", showBroadcast);
  fprintf(stdout, "--var2=[%d]\n", vartwo);
  fprintf(stdout, "--var3=[%f]\n", varthr);
  fprintf(stdout, "--info=[%s]\n", info);
  fprintf(stdout, "-ip=[%s]\n", inet_ntoa(ip_addr));
  fprintf(stdout, "-ho=[%s]\n", inet_ntoa(host));
  */


  fflush(stdout);


  midnightcode_logo(0,
    MIDNIGHTCODE_LICENSE_STYLE_BLOOD_MOON);
  midnightcode_license(0,
    MIDNIGHTCODE_LICENSE_STYLE_BLOOD_MOON, 
    MIDNIGHTCODE_LICENSE_TEXT_ALL);


  // Status Title
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_H1,
                           MIDNIGHTCODE_STATUS_STYLE_NORMAL,
                           "Welcome to %s", argv[0]);

  // Status Section
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_H2,
                           MIDNIGHTCODE_STATUS_STYLE_SOFT,
                           "Test set for %s styles", "Logo");

  // Status
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_SOFT,
                           "This is status text that is long "
                           "and c%d%dl to look at too", 0,0);
  midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_OKAY);

  // Status
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_NORMAL,
                           "This is status text that is long "
                           "and c%d%dl to look at too", 0,0);
  midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_WARN);

  // Status
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_STRONG,
                           "This is status text");
  midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_FAIL);

  // Status blurb
  fprintf(stdout, "\n");
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_BLURB,
                           MIDNIGHTCODE_STATUS_STYLE_UNKNOWN,
                           "There appear to be no network card drivers loaded.");
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_BLURB,
                           MIDNIGHTCODE_STATUS_STYLE_UNKNOWN,
                           "Your card is not supported. Please see the CHAOS");
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_BLURB,
                           MIDNIGHTCODE_STATUS_STYLE_UNKNOWN,
                           "HOWTO or FAQ for more information or email the");
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_BLURB,
                           MIDNIGHTCODE_STATUS_STYLE_UNKNOWN,
                           "list and provide details of this system.");
  fprintf(stdout, "\n");
  fflush(stdout);

  // Status
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_UNKNOWN,
                           "This is status text");
  midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_UNKNOWN);

  fprintf(stdout, "\n\n");


  // EXEC TEST
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_SOFT,
                           "Exec output .. ");
  int options = 0;
  int pid;
  options |= MIDNIGHTCODE_PROCESS_OPTION_WAITTERM;
  options |= MIDNIGHTCODE_PROCESS_OPTION_NULLIO;
  options |= MIDNIGHTCODE_PROCESS_OPTION_EXITCODE;
  // options |= MIDNIGHTCODE_PROCESS_OPTION_GETPID;
  if((pid = midnightcode_process("./go", options, 0)) != 0) {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_FAIL);
  } else {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_OKAY);
  }

  fprintf(stdout, "\n\n");


  // List testing
  midnightcode_list_init(list_struct_head, entry_struct_name);
  if(vartwo < 5)
    vartwo = 5;

  op = NULL;
  for(n=1; n<=vartwo; n++) {
    if(!list_silent)
      printf("Append list entry %d\n", n);
    np = malloc(sizeof(struct entry_struct_name));
    memset(np, 0, sizeof(struct entry_struct_name));
    np->test_val = n;
    midnightcode_list_append(&list_struct_head, np);
    if(n==2)
      op = np;
  }
  n = 1999;
  printf("Insert list entry %d\n", n);
  np = malloc(sizeof(struct entry_struct_name));
  np->test_val = n;
  midnightcode_list_insert(&list_struct_head, np);
  printf("List count: %d\n", (&(list_struct_head))->count);

  midnightcode_list_for_each(np, &list_struct_head) {
    if(!list_silent)
      printf("List entry: %d\n", np->test_val);
  }

  printf("Remove list entry 2\n");
  midnightcode_list_remove(&list_struct_head, op);
  printf("ent2->test_val = [%d]\n", op->test_val);
  free(op);
  printf("List count: %d\n", (&(list_struct_head))->count);

  midnightcode_list_for_each(np, &list_struct_head) {
    if(!list_silent)
      printf("List entry: %d\n", np->test_val);
  }
  np = (&(list_struct_head))->last;
  printf("Last list entry: %d\n", np->test_val);

  printf("Remove last list entry\n");
  midnightcode_list_remove(&list_struct_head, np);
  free(np);

  printf("----------------\n");

  np = (&(list_struct_head))->last;
  printf("Last: %d\n", np->test_val);
  np = np->MIDNIGHTCODE_LIST_ENTRIES.prev;
  printf("Last -1: %d\n", np->test_val);

  printf("List count: %d\n", (&(list_struct_head))->count);

  
  exit(0);
}

