/*
 * XML DRI client-side driver configuration
 * Copyright (C) 2003 Felix Kuehling
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 */
/**
 * \file xmlconfig.h
 * \brief Driver-independent client-side part of the XML configuration
 * \author Felix Kuehling
 */

#ifndef __XMLCONFIG_H
#define __XMLCONFIG_H

#include "util/mesa-sha1.h"
#include "util/ralloc.h"
#include <string.h>

#define STRING_CONF_MAXLEN 25

/** \brief Option data types */
typedef enum driOptionType {
    DRI_BOOL, DRI_ENUM, DRI_INT, DRI_FLOAT, DRI_STRING
} driOptionType;

/** \brief Option value */
typedef union driOptionValue {
    unsigned char _bool; /**< \brief Boolean */
    int _int;      /**< \brief Integer or Enum */
    float _float;  /**< \brief Floating-point */
    char *_string;   /**< \brief String */
} driOptionValue;

/** \brief Single range of valid values
 *
 * For empty ranges (a single value) start == end */
typedef struct driOptionRange {
    driOptionValue start; /**< \brief Start */
    driOptionValue end;   /**< \brief End */
} driOptionRange;

/** \brief Information about an option */
typedef struct driOptionInfo {
    char *name;             /**< \brief Name */
    driOptionType type;     /**< \brief Type */
    driOptionRange *ranges; /**< \brief Array of ranges */
    unsigned int nRanges;   /**< \brief Number of ranges */
} driOptionInfo;

/** \brief Option cache
 *
 * \li One in <driver>Screen caching option info and the default values
 * \li One in each <driver>Context with the actual values for that context */
typedef struct driOptionCache {
    driOptionInfo *info;
  /**< \brief Array of option infos
   *
   * Points to the same array in the screen and all contexts */
    driOptionValue *values;	
  /**< \brief Array of option values
   *
   * \li Default values in screen
   * \li Actual values in contexts 
   */
    unsigned int tableSize;
  /**< \brief Size of the arrays
   *
   * In the current implementation it's not actually a size but log2(size).
   * The value is the same in the screen and all contexts. */
} driOptionCache;

/** \brief Parse XML option info from configOptions
 *
 * To be called in <driver>CreateScreen 
 *
 * \param info    pointer to a driOptionCache that will store the option info
 * \param configOptions   XML document describing available configuration opts
 *
 * For the option information to be available to external configuration tools
 * it must be a public symbol __driConfigOptions. It is also passed as a
 * parameter to driParseOptionInfo in order to avoid driver-independent code
 * depending on symbols in driver-specific code. */
void driParseOptionInfo (driOptionCache *info,
			 const char *configOptions);
/** \brief Initialize option cache from info and parse configuration files
 *
 * To be called in <driver>CreateContext. screenNum and driverName select
 * device sections. */
void driParseConfigFiles (driOptionCache *cache, const driOptionCache *info,
			  int screenNum, const char *driverName);
/** \brief Destroy option info
 *
 * To be called in <driver>DestroyScreen */
void driDestroyOptionInfo (driOptionCache *info);
/** \brief Destroy option cache
 *
 * To be called in <driver>DestroyContext */
void driDestroyOptionCache (driOptionCache *cache);

/** \brief Check if there exists a certain option */
unsigned char driCheckOption (const driOptionCache *cache, const char *name,
			  driOptionType type);

/** \brief Query a boolean option value */
unsigned char driQueryOptionb (const driOptionCache *cache, const char *name);
/** \brief Query an integer option value */
int driQueryOptioni (const driOptionCache *cache, const char *name);
/** \brief Query a floating-point option value */
float driQueryOptionf (const driOptionCache *cache, const char *name);
/** \brief Query a string option value */
char *driQueryOptionstr (const driOptionCache *cache, const char *name);

/**
 * Returns a hash of the options for this application.
 */
static inline void
driComputeOptionsSha1(const driOptionCache *cache, unsigned char *sha1)
{
   void *ctx = ralloc_context(NULL);
   char *dri_options = ralloc_strdup(ctx, "");

   for (int i = 0; i < 1 << cache->tableSize; i++) {
      if (cache->info[i].name == NULL)
         continue;

      bool ret = false;
      switch (cache->info[i].type) {
      case DRI_BOOL:
         ret = ralloc_asprintf_append(&dri_options, "%s:%u,",
                                      cache->info[i].name,
                                      cache->values[i]._bool);
         break;
      case DRI_INT:
      case DRI_ENUM:
         ret = ralloc_asprintf_append(&dri_options, "%s:%d,",
                                      cache->info[i].name,
                                      cache->values[i]._int);
         break;
      case DRI_FLOAT:
         ret = ralloc_asprintf_append(&dri_options, "%s:%f,",
                                      cache->info[i].name,
                                      cache->values[i]._float);
         break;
      case DRI_STRING:
         ret = ralloc_asprintf_append(&dri_options, "%s:%s,",
                                      cache->info[i].name,
                                      cache->values[i]._string);
         break;
      default:
         unreachable("unsupported dri config type!");
      }

      if (!ret) {
         break;
      }
   }

   _mesa_sha1_compute(dri_options, strlen(dri_options), sha1);
   ralloc_free(ctx);
}

#endif
