/*  From preliminary work (pull.vect) by Dave Gerdes - CERL
 *  created by:         R.L.Glenn, SCS
 *  modified to function by RB 5/2000
 *
 * Function reclass() reads input vector map and writes reclassed elements to output map.
 *
 * Arguments:
 * in_name - name of input vector map
 * out_name - name of output vector map
 * new - reclass table
 * type - elements type 
 * optiond - do not output boundaries between areas with the same cat 
 *
 * Returns:
 * number of elements created or -1 on error
 */

#include <stdlib.h>
#include <string.h>
#include <grass/gis.h>
#include <grass/dbmi.h>
#include <grass/Vect.h>

int reclass ( struct Map_info *In, struct Map_info *Out, int type, int field, dbCatValArray *cvarr, int dissolve)
{
    int i, nlines, nareas, line, area, ltype, old_cat, new_cat;	
    int nocat = 0, rclelem=0, negative=0;
    struct line_pnts *Points;
    struct line_cats *Cats, *NewCats;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct ();
    NewCats = Vect_new_cats_struct ();

    /* --------------------- Lines Section ------------------------------- */
    /* Cycle through all lines */
    nlines = Vect_get_num_lines (In);
    for ( line = 1; line <= nlines; line++) { 
	G_percent(line, nlines, 1);
	
	ltype = Vect_read_line ( In, Points, Cats, line );

	Vect_reset_cats ( NewCats );
	
	for ( i = 0 ; i < Cats->n_cats; i++ ) {
	    if ( (ltype & type) && Cats->field[i] == field ) { /* reclass */
		old_cat =  Cats->cat[i];
		G_debug (3, "  old_cat = %d", old_cat ); 

		if ( db_CatValArray_get_value_int ( cvarr, old_cat, &new_cat ) != DB_OK ) {
		    nocat++;
		} else { 
		    G_debug (3, "  new_cat = %d", new_cat ); 

		    if ( new_cat < 0 ) {
			negative++;
		    } else {
			Vect_cat_set ( NewCats, field, new_cat );
		    }
		    rclelem++;
		}
	    } else { /* copy */
		Vect_cat_set ( NewCats, Cats->field[i], Cats->cat[i] );
	    }
	}	
	Vect_write_line (Out, ltype, Points, NewCats);
    }

    if ( nocat > 0 )
	G_warning ("For %d elements no new category was defined", nocat );
    
    if ( negative > 0 )
	G_warning ("For %d elements requested negative category (ignored, no category in output)", negative );

    return(rclelem) ;
}

