/*

                                   _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-2006
       "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

*/

/* midnightcode-switch.c :: Midnight Code command-line switch library	*/


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

#include "midnightcode-colour.h"
#include "midnightcode-parse.h"
#include "midnightcode-switch.h"


int
midnightcode_switch_usage(int style, char * execname,
                          struct midnightcode_switch_t * switches) {
  struct midnightcode_switch_t* this_switch;
  char param[10];
  char short_s[5];
  char long_s[13];
  char option_s[32];
  int  switchn;


  fprintf(stdout, "\n");
  fprintf(stdout, "  Usage: %s [OPTIONS]\n", execname);
  fprintf(stdout, "\n");
  fprintf(stdout, "    Valid options, and their values, include;\n");
  for(this_switch = switches, switchn = 0;
      this_switch[switchn].variable != NULL;
      switchn++) {

    memset(param, 0, 10);
    switch(this_switch[switchn].type) {
      case MIDNIGHTCODE_PARSE_TYPE_NONE:
        break;

      case MIDNIGHTCODE_PARSE_TYPE_STRING:
        strncpy(param, "=STRING", 9);
        break;

      case MIDNIGHTCODE_PARSE_TYPE_INT:
        strncpy(param, "=INTEGER", 9);
        break;

      case MIDNIGHTCODE_PARSE_TYPE_LONG:
        strncpy(param, "=LONG", 9);
        break;

      case MIDNIGHTCODE_PARSE_TYPE_VAL:
        break;

      case MIDNIGHTCODE_PARSE_TYPE_FLOAT:
        strncpy(param, "=FLOAT", 9);
        break;

      case MIDNIGHTCODE_PARSE_TYPE_DOUBLE:
        strncpy(param, "=DOUBLE", 9);
        break;

      case MIDNIGHTCODE_PARSE_TYPE_HOST:
        strncpy(param, "=HOST", 9);
        break;

      case MIDNIGHTCODE_PARSE_TYPE_IP:
        strncpy(param, "=IP", 9);
        break;

      default:
        break;
    }

    memset(short_s, 0, 5);
    memset(long_s, 0, 13);
    memset(option_s, 0, 32);

    snprintf(short_s, 3, "%s", this_switch[switchn].short_s);
    strncat(short_s, ",", 4);
    snprintf(long_s, 12, "%s", this_switch[switchn].long_s);

    snprintf(option_s, 31, "-%-4.4s --%s%s", short_s,
             this_switch[switchn].long_s, param);

    switch(style) {
      case MIDNIGHTCODE_SWITCH_STYLE_SOFT:
        fprintf(stdout, MIDNIGHTCODE_COLOUR_DK_GREY
                        "      %-30.30s %-42.42s\n"
                        MIDNIGHTCODE_COLOUR_NORMAL,
                        option_s, this_switch[switchn].descript_s);
        fflush(stdout);
        break;

      case MIDNIGHTCODE_SWITCH_STYLE_NORMAL:
        fprintf(stdout, MIDNIGHTCODE_COLOUR_NORMAL
                        "      --%-12.12s -%-3.3s %-8.8s %-45.45s\n"
                        MIDNIGHTCODE_COLOUR_NORMAL,
                        this_switch[switchn].long_s,
                        this_switch[switchn].short_s, param,
                        this_switch[switchn].descript_s);
        fflush(stdout);
        break;

      case MIDNIGHTCODE_SWITCH_STYLE_STRONG:
        fprintf(stdout, MIDNIGHTCODE_COLOUR_WHITE
                        "      --%-12.12s -%-3.3s %-8.8s %-45.45s\n"
                        MIDNIGHTCODE_COLOUR_NORMAL,
                        this_switch[switchn].long_s,
                        this_switch[switchn].short_s, param,
                        this_switch[switchn].descript_s);
        fflush(stdout);
        break;

      default:
        fprintf(stdout, MIDNIGHTCODE_COLOUR_YELLOW
                        "      --%-12.12s -%-3.3s %-8.8s %-45.45s\n"
                        MIDNIGHTCODE_COLOUR_NORMAL,
                        this_switch[switchn].long_s,
                        this_switch[switchn].short_s, param,
                        this_switch[switchn].descript_s);
        fflush(stdout);
        break;
    }
  }
  fprintf(stdout, "\n");
  fflush(stdout);

  return 0;
}



int
midnightcode_switch_process(int argc, char** argv,
                            struct midnightcode_switch_t * switches) {
  struct midnightcode_switch_t* this_switch;
  char long_s[64], short_s[4];
  int  argn, switchn;
  int  matched, offset;
  char equal_buf[1024];
  int  equal_check;
  char * buffer_p;


  for(argn = 1; argn < argc && argv[argn][0] == '-'; argn++) {
    for(this_switch = switches, switchn = 0;
        this_switch[switchn].variable != NULL;
        switchn++) {

      memset(long_s, 0, 64);
      memset(short_s, 0, 4);
      if(this_switch[switchn].long_s != NULL) {
        strncpy(long_s, "--", 63);
        strncat(long_s, this_switch[switchn].long_s, 61);
      }
      if(this_switch[switchn].short_s != NULL) {
        strncpy(short_s, "-", 3);
        strncat(short_s, this_switch[switchn].short_s, 2);
      }

      matched = 0;
      offset = 0;
      equal_check = 0;

      if(*long_s != '\0' &&
         strcmp(argv[argn], long_s) == 0) {
        matched = 1;
      } else if(*short_s != '\0' &&
                strcmp(argv[argn], short_s) == 0) {
        matched = 1;
      } else if(*long_s != '\0' &&
                strncmp(argv[argn], long_s, strlen(long_s)) == 0) {
        matched = 1;
        offset = strlen(long_s);
      } else if(*short_s != '\0' &&
                strncmp(argv[argn], short_s, strlen(short_s)) == 0) {
        matched = 1;
        offset = strlen(short_s);
      }

      if(offset) {
        if(argv[argn][offset] == '=') {
          offset++;
          memset(equal_buf, 0, 1024);
          strncpy(equal_buf, &argv[argn][offset], 1023);
          equal_check = 1;
        } else {
          offset = 0;
          matched = 0;
        }
      }

      if(matched) {

        buffer_p = NULL;

        if(equal_check) {
          buffer_p = equal_buf;
        } else {
          if(this_switch[switchn].type != MIDNIGHTCODE_PARSE_TYPE_NONE &&
            this_switch[switchn].type != MIDNIGHTCODE_PARSE_TYPE_VAL) {
            if(argn + 1 >= argc)
              break;
	    argn++;
            buffer_p = argv[argn];
          }
        }
        if(midnightcode_parse_strtovar(this_switch[switchn].variable,
                            buffer_p,
                            this_switch[switchn].length,
                            this_switch[switchn].value,
                            this_switch[switchn].type))
          return argn;

        break;
      }
    }
    if(this_switch[switchn].variable == NULL)
      return argn;
 
  }
  if(argn != argc)
    return argn;

  return 0;
}


