#!/usr/bin/env python
# -*- coding: utf-8 -*-

########################################################################
#
# MODULE:       r.recode_attribute
# AUTHOR(S):    Paulo van Breugel <p.vanbreugel AT gmail.com>
# PURPOSE:      Recode raster to one or more new layers using an
#               attribute table (csv file) as input
#
# COPYRIGHT: (C) 2015 Paulo van Breugel
#            http://ecodiv.org
#            http://pvanb.wordpress.com/
#
#            This program is free software under the GNU General Public
#            License (>=v2). Read the file COPYING that comes with GRASS
#            for details.
#
########################################################################
#
#%Module
#% description: Recode raster using attribute table (csv file) as input.
#% keyword: raster
#% keyword: recode
#%End

#%option
#% key: input
#% type: string
#% gisprompt: old,cell,raster
#% description: Input map
#% key_desc: name
#% required: yes
#% multiple: no
#%end

#%option
#% key: output
#% type: string
#% gisprompt: old,cell,raster
#% description: name(s) output layer(s)
#% key_desc: name
#% required: yes
#% multiple: no
#%end

#%option G_OPT_F_INPUT
#% key: rules
#% label: Full path to rules file
#% required: yes
#%end

#%flag:
#% key: a
#% description: Align the current region to the input raster map
#%end

# import libraries
import os
import sys
import numpy as np
import tempfile
import grass.script as grass

# main function
def main():

    # check if GISBASE is set
    if "GISBASE" not in os.environ:
    # return an error advice
       grass.fatal("You must be in GRASS GIS to run this program")

    # input raster map and parameters
    inputmap = options['input']
    outBase = options['output']
    rules = options['rules']
    outNames = outBase.split(',')
    lengthNames = len(outNames)
    flag_a = flags['a']

    # Get attribute data
    myData = np.genfromtxt(rules, delimiter=',', skip_header=1)
    nmsData = np.genfromtxt(rules, delimiter=',', names=True)
    dimData = myData.shape
    nmsData = nmsData.dtype.names

    # Create recode maps
    numVar = xrange(dimData[1]-1)
    for x in numVar:
        y = x + 1
        myRecode = np.column_stack((myData[:,0], myData[:,0], myData[:,y]))

        fd1, tmpname = tempfile.mkstemp()
        np.savetxt(tmpname, myRecode, delimiter=":")

        if len(numVar) == lengthNames:
            nmOutput = outNames[x]
        else:
            nmOutput = outNames[0] + '_' + nmsData[y]

        cf = grass.find_file(name=nmOutput, element = 'cell',
                          mapset=grass.gisenv()['MAPSET'])
        if cf['fullname'] != '':
            grass.fatal("The layer " + nmOutput + " already exist in this mapset")

        if flag_a:
            grass.run_command('r.recode',
                    input = inputmap,
                    output = nmOutput,
                    rules = tmpname,
                    flags = "a")
        else:
            grass.run_command('r.recode',
                    input = inputmap,
                    output = nmOutput,
                    rules = tmpname)
        os.close(fd1)
        os.remove(tmpname)


if __name__ == "__main__":
    options, flags = grass.parser()
    sys.exit(main())

