
/****************************************************************************
 *
 * MODULE:       ps.map
 * FILE:         catval.c
 * AUTHOR(S):    Martin Landa <landa.martin@gmail.com>
 *		 Hamish Bowman
 * PURPOSE:      Support functions for loading dynamic symbol attributes
 *		 Used in PS_vpoints_plot()
 * COPYRIGHT:    (C) 2007 by the GRASS Development Team
 *
 *               This program is free software under the GNU General Public
 *               License (>=v2). Read the file COPYING that comes with GRASS
 *               for details.
 *
 *****************************************************************************/

#include <grass/gis.h>
#include <grass/Vect.h>
#include <grass/dbmi.h>
#include <grass/glocale.h>

#include "vector.h"

/**
 * \fn int load_catval_array_rgb (struct Map_info* map, int vec, dbCatValArray* cvarr_rgb)
 *
 * \brief Loads categories and RGB color definition into dbCatValArray structure
 *
 * \param map: poiter to a vector Map_info structure
 * \param level: layer number identifier
 * \param level: output dbCatValArray structure
 *
 * \return number of records or -1 if it fails
 */

int load_catval_array_rgb(struct Map_info *map, int vec,
			  dbCatValArray * cvarr_rgb)
{
    int i, nrec, ctype;
    struct field_info *Fi;
    dbDriver *driver;

    G_debug(2, "Loading dynamic symbol colors ...");
    db_CatValArray_init(cvarr_rgb);

    Fi = Vect_get_field(map, vector.layer[vec].field);
    if (Fi == NULL) {
	G_fatal_error(_("Unable to get layer info for vector map"));
    }

    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    nrec = db_select_CatValArray(driver, Fi->table, Fi->key,
				 vector.layer[vec].rgbcol, NULL, cvarr_rgb);

    G_debug(3, "nrec_rgb = %d", nrec);

    ctype = cvarr_rgb->ctype;
    if (ctype != DB_C_TYPE_STRING)
	G_fatal_error(_("Column type not supported (must be string)"));

    if (nrec < 0)
	G_fatal_error(_("Unable to select data from table"));

    G_debug(2, "\nRGB column: %d records selected from table", nrec);

    for (i = 0; i < cvarr_rgb->n_values; i++) {
	G_debug(4, "cat = %d val = %s", cvarr_rgb->value[i].cat,
		cvarr_rgb->value[i].val.s->string);
    }

    db_close_database_shutdown_driver(driver);

    return nrec;
}



/**** Probably merge _size and _rot fns into a single _double() fn; all that is
 **** needed is to pass the column name from the vector struct to the fn as well.
 */

/**
 * \fn int load_catval_array_size (struct Map_info* map, int vec, dbCatValArray* cvarr_size)
 *
 * \brief Loads categories and dynamic size values into dbCatValArray structure
 *
 * \param map: poiter to a vector Map_info structure
 * \param level: layer number identifier
 * \param level: output dbCatValArray structure
 *
 * \return number of records or -1 if it fails
 */

int load_catval_array_size(struct Map_info *map, int vec,
			   dbCatValArray * cvarr_size)
{
    int i, nrec, ctype;
    struct field_info *Fi;
    dbDriver *driver;

    G_debug(2, "Loading dynamic symbol sizes ...");
    db_CatValArray_init(cvarr_size);

    Fi = Vect_get_field(map, vector.layer[vec].field);
    if (Fi == NULL) {
	G_fatal_error(_("Unable to get layer info for vector map"));
    }

    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    /* Note do not check if the column exists in the table because it may be expression */

    /* TODO: only select values we need instead of all in column */
    nrec = db_select_CatValArray(driver, Fi->table, Fi->key,
				 vector.layer[vec].sizecol, NULL, cvarr_size);

    G_debug(3, "nrec = %d", nrec);

    ctype = cvarr_size->ctype;
    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Size column type must be numeric"));

    if (nrec < 0)
	G_fatal_error(_("Unable to select data from table"));
    G_debug(2, "\nSize column: %d records selected from table", nrec);

    db_close_database_shutdown_driver(driver);

    for (i = 0; i < cvarr_size->n_values; i++) {
	if (ctype == DB_C_TYPE_INT) {
	    G_debug(4, "cat = %d val = %d", cvarr_size->value[i].cat,
		    cvarr_size->value[i].val.i);
	}
	else if (ctype == DB_C_TYPE_DOUBLE) {
	    G_debug(4, "cat = %d val = %f", cvarr_size->value[i].cat,
		    cvarr_size->value[i].val.d);
	}
    }

    return nrec;
}



/**
 * \fn int load_catval_array_rot (struct Map_info* map, int vec, dbCatValArray* cvarr_rot)
 *
 * \brief Loads categories and dynamic rotation values into dbCatValArray structure
 *
 * \param map: poiter to a vector Map_info structure
 * \param level: layer number identifier
 * \param level: output dbCatValArray structure
 *
 * \return number of records or -1 if it fails
 */

int load_catval_array_rot(struct Map_info *map, int vec,
			  dbCatValArray * cvarr_rot)
{
    int i, nrec, ctype;
    struct field_info *Fi;
    dbDriver *driver;

    G_debug(2, "Loading dynamic symbol rotation ...");
    db_CatValArray_init(cvarr_rot);

    Fi = Vect_get_field(map, vector.layer[vec].field);
    if (Fi == NULL) {
	G_fatal_error(_("Unable to get layer info for vector map"));
    }

    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    /* Note do not check if the column exists in the table because it may be expression */

    /* TODO: only select values we need instead of all in column */
    nrec = db_select_CatValArray(driver, Fi->table, Fi->key,
				 vector.layer[vec].rotcol, NULL, cvarr_rot);

    G_debug(3, "nrec = %d", nrec);

    ctype = cvarr_rot->ctype;

    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Rotation column type must be numeric"));

    if (nrec < 0)
	G_fatal_error(_("Unable to select data from table"));

    G_debug(2, "\nRotate column: %d records selected from table", nrec);

    db_close_database_shutdown_driver(driver);

    for (i = 0; i < cvarr_rot->n_values; i++) {
	if (ctype == DB_C_TYPE_INT) {
	    G_debug(4, "cat = %d val = %d", cvarr_rot->value[i].cat,
		    cvarr_rot->value[i].val.i);
	}
	else if (ctype == DB_C_TYPE_DOUBLE) {
	    G_debug(4, "cat = %d val = %f", cvarr_rot->value[i].cat,
		    cvarr_rot->value[i].val.d);
	}
    }

    return nrec;
}
