// Copyright 2012 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
//  Utility functions used by the example programs.
//

#include "./example_util.h"

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

#include "webp/mux_types.h"
#include "../imageio/imageio_util.h"

//------------------------------------------------------------------------------
// String parsing

uint32_t ExUtilGetUInt(const char* const v, int base, int* const error) {
  char* end = NULL;
  const uint32_t n = (v != NULL) ? (uint32_t)strtoul(v, &end, base) : 0u;
  if (end == v && error != NULL && !*error) {
    *error = 1;
    fprintf(stderr, "Error! '%s' is not an integer.\n",
            (v != NULL) ? v : "(null)");
  }
  return n;
}

int ExUtilGetInt(const char* const v, int base, int* const error) {
  return (int)ExUtilGetUInt(v, base, error);
}

int ExUtilGetInts(const char* v, int base, int max_output, int output[]) {
  int n, error = 0;
  for (n = 0; v != NULL && n < max_output; ++n) {
    const int value = ExUtilGetInt(v, base, &error);
    if (error) return -1;
    output[n] = value;
    v = strchr(v, ',');
    if (v != NULL) ++v;   // skip over the trailing ','
  }
  return n;
}

float ExUtilGetFloat(const char* const v, int* const error) {
  char* end = NULL;
  const float f = (v != NULL) ? (float)strtod(v, &end) : 0.f;
  if (end == v && error != NULL && !*error) {
    *error = 1;
    fprintf(stderr, "Error! '%s' is not a floating point number.\n",
            (v != NULL) ? v : "(null)");
  }
  return f;
}

//------------------------------------------------------------------------------

static void ResetCommandLineArguments(int argc, const char* argv[],
                                      CommandLineArguments* const args) {
  assert(args != NULL);
  args->argc_ = argc;
  args->argv_ = argv;
  args->own_argv_ = 0;
  WebPDataInit(&args->argv_data_);
}

void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
  if (args != NULL) {
    if (args->own_argv_) {
      free((void*)args->argv_);
      WebPDataClear(&args->argv_data_);
    }
    ResetCommandLineArguments(0, NULL, args);
  }
}

#define MAX_ARGC 16384
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
                                   CommandLineArguments* const args) {
  if (args == NULL || argv == NULL) return 0;
  ResetCommandLineArguments(argc, argv, args);
  if (argc == 1 && argv[0][0] != '-') {
    char* cur;
    const char sep[] = " \t\r\n\f\v";
    if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) {
      return 0;
    }
    args->own_argv_ = 1;
    args->argv_ = (const char**)malloc(MAX_ARGC * sizeof(*args->argv_));
    if (args->argv_ == NULL) return 0;

    argc = 0;
    for (cur = strtok((char*)args->argv_data_.bytes, sep);
         cur != NULL;
         cur = strtok(NULL, sep)) {
      if (argc == MAX_ARGC) {
        fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC);
        return 0;
      }
      assert(strlen(cur) != 0);
      args->argv_[argc++] = cur;
    }
    args->argc_ = argc;
  }
  return 1;
}

//------------------------------------------------------------------------------

int ExUtilReadFileToWebPData(const char* const filename,
                             WebPData* const webp_data) {
  const uint8_t* data;
  size_t size;
  if (webp_data == NULL) return 0;
  if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
  webp_data->bytes = data;
  webp_data->size = size;
  return 1;
}
