
# File: gvpy.py
# Version: v0.5
# 2016/02/10

__author__ = """Oscar Martinez Olmos <masquesig@gmail.com>"""

import gvsig
import geom
import gvsig_raster
from org.gvsig.app import ApplicationLocator
from org.gvsig.fmap.dal import DALLocator
import os.path
from org.gvsig.andami import PluginsLocator
from org.gvsig.fmap.mapcontext import MapContextLocator
import java.awt
import java.awt.event
import java.awt.geom
from java.io import File
from java.util import ArrayList

import uselib
uselib.use_plugin("org.gvsig.geoprocess.app.mainplugin")
uselib.use_plugin("org.gvsig.gdal.app.ogr.mainplugin")

from es.unex.sextante.core import Sextante, OutputFactory, AnalysisExtent
from es.unex.sextante.outputs import FileOutputChannel
from es.unex.sextante.gui.core import SextanteGUI
from es.unex.sextante.dataObjects import IRasterLayer
from es.unex.sextante.parameters import RasterLayerAndBand

from org.gvsig.geoprocess.lib.sextante.dataObjects import FlyrVectIVectorLayer, FLyrRasterIRasterLayer, TableDocumentITable
from org.gvsig.fmap.mapcontext.layers import FLayer
from java.awt.geom import RectangularShape, Rectangle2D
from org.gvsig.fmap.mapcontext.layers.vectorial import FLyrVect
from org.gvsig.raster.fmap.layers import DefaultFLyrRaster
from org.gvsig.app.project.documents.view import DefaultViewDocument
from org.gvsig.fmap.dal import DALLocator
from org.gvsig.fmap.mapcontext import MapContextLocator

#Constant
TYPE_POLYGON = 0
TYPE_LINE = 1
TYPE_POINT = 2

#With True will appear a lot of extra info about all steps through the process
DEV_INFO = False

class Geoprocess:
    def __init__(self):
      Sextante.initialize()
      SextanteGUI.initialize()
      self.__FlyrVectIVectorLayer = None
      self.__outputFactory = SextanteGUI.getOutputFactory()
      self.__algorithms = dict()
      self.__defaultAE = None #default AExtension

      keySetIterator = Sextante.getAlgorithms().keySet().iterator()
      while(keySetIterator.hasNext()):
        key = keySetIterator.next()
        algorithms = Sextante.getAlgorithms().get(str(key))
        for name in algorithms.keySet():
          self.__algorithms[str(name)] = algorithms.get(name)

    def __createSextanteLayer(self, layer):
        """ gvsig layer -> SEXTANTE """
        slayer = FlyrVectIVectorLayer()
        slayer.create(layer)
        return slayer

    def __createSextanteRaster(self, layer):
        """ gvsig raster -> SEXTANTE """
        rlayer = FLyrRasterIRasterLayer()
        rlayer.create(layer)
        return rlayer

    def __createSextanteTable(self, layer):
        """ gvsig table -> SEXTANTE """
        table = TableDocumentITable()
        table.create(layer)
        return table

    def getAlgorithms(self):
        return self.__algorithms

    def __defineParameters_str2value(self, i, param, kwparams):
        if param.getParameterName() in kwparams:
            paramValue = kwparams[param.getParameterName()]
        else:
            paramValue = kwparams[i]

        #Input params: Tranform STRING to NUMERIC
        cond1 = (str(param) == "Numerical Value")
        cond2 = (str(param) == "Selection")
        isstr = isinstance(paramValue, str)
        cond4 = (str(param) == "Boolean")
        cond5 = (str(param) == "Table Field")
        if "Multi" in (str(param)):
            cond6 = True
        else:
            cond6 = False
        cond7 = (str(param) == "Point")

        if isstr:
            if cond1:
                paramValue = float(paramValue)
            elif cond2:
                paramValue = int(paramValue)
            elif cond4:
                paramValue = eval(paramValue.capitalize())
            elif cond5:
                paramValue = int(paramValue)
                print "TAble field: ", paramValue
            elif cond6:
                #  <type 'java.util.ArrayList'>
                paramValue = list(paramValue)
            elif cond7: #Point
                paramValue = paramValue.split(',')
                x = float(paramValue[0])
                y = float(paramValue[1])
                paramValue = java.awt.geom.Point2D.Double(x, y)
            else: #is str
                pass
        else:
            if cond7: #punto de gvsig. agregar condicion punto
                x = paramValue.getX()
                y = paramValue.getY()
                paramValue = java.awt.geom.Point2D.Double(x, y)
        if DEV_INFO:
            print "Param Name: ", param.getParameterName()
            print "Param: ", param
            print "Resulta: ", paramValue, type(paramValue)
        return paramValue

    def __defineParameters_vector2sextante(self, param, paramValue):
                if isinstance(paramValue, str):
                    layer = gvsig.currentView().getLayer(paramValue)
                    paramValue = self.__createSextanteLayer(layer())
                else:
                    paramValue = self.__createSextanteLayer(paramValue())

                if DEV_INFO: print "Extent add"
                if self.__defaultAE == None:
                    self.__defaultAE = AnalysisExtent(paramValue)
                else:
                    self.__defaultAE.addExtent(AnalysisExtent(paramValue))
                if DEV_INFO: print "PARAM VALUE 1: ", paramValue
                return paramValue

    def __defineParameters_multi2sextante(self, param, paramValue):
                if DEV_INFO: print "PARAM VALUE PRE", paramValue
                paramValue2 = []
                for i in paramValue:
                    if isinstance(i, str):
                        layer = gvsig.currentView().getLayer(i)
                        print "--------------- lidar: ", layer
                        i = self.__createSextanteLayer(layer)
                        ii = self.__createSextanteLayer(layer)

                    else:
                        if DEV_INFO: print type(i)
                        if isinstance(i, tuple): #si dentro de la lista viene una tupla identificamos que es un raster y su banda
                            rlb = RasterLayerAndBand(self.__createSextanteRaster(i[0]),i[1])  #puesta numero de banda
                            ii = self.__createSextanteRaster(i[0])
                            i = rlb
                            if DEV_INFO: print "RASTERLAYERBAND", rlb
                        else:
                            if str(type(i)) == "<type 'org.gvsig.raster.fmap.layers.DefaultFLyrRaster'>":
                                ii = self.__createSextanteRaster(i)
                                i = self.__createSextanteRaster(i)
                            else:
                                ii = self.__createSextanteLayer(i())
                                i = self.__createSextanteLayer(i())
                        if DEV_INFO: print "createStextenatnte Layer i :", i
                        paramValue2.append(i)
                    if self.__defaultAE == None:
                            try:
                                self.__defaultAE = AnalysisExtent(AnalysisExtent(ii))
                                self.__defaultAE.setCellSize(0.49) ### test
                                self.__defaultAE.setCellSizeZ(0.49)  ### test
                                #self.__defaultAE.addExtent( )
                                if DEV_INFO: print "----------- ini defaultAE"
                            except:
                                try:
                                    self.__defaultAE = AnalysisExtent(ii())
                                except:
                                    self.__defaultAE = AnalysisExtent(ii)
                    elif self.__defaultAE != None:
                            try:
                                ae = self.__defaultAE
                                #ae.addExtent(AnalysisExtent(ii))
                                if DEV_INFO: print "------------ diferente defaultAE"
                            except:

                                self.__defaultAE.addExtent(AnalysisExtent(ii()))
                    """
                    if self.__defaultAE == None:
                        try:
                            self.__defaultAE = AnalysisExtent(i)
                        except:
                            print "excepttttttttttttttt", i
                            ae = i.getRasterLayer()
                            self.__defaultAE = AnalysisExtent(ae)
                    else:
                        try:

                            self.__defaultAE.addExtent(AnalysisExtent(i))
                        except:
                            print 'exceptttttttttttttt 222222222"', i
                            ae = i.getRasterLayer()
                            print 'ae',ae
                            self.__defaultAE.addExtent(AnalysisExtent(ae))
                            #print self.__defaultAE
                    """

                paramValue = paramValue2

                if DEV_INFO:
                    print "PARAM VALUE 2: ", paramValue
                    print "****************** CONDI6: ", paramValue
                    print "****************** CONDI6: ", ArrayList(paramValue)
                newParamValue = ArrayList()
                for i in paramValue:
                    newParamValue.add(i)
                paramValue = newParamValue
                #print "***************** CONDI6: ", paramValue
                #from es.unex.sextante.parameters import ParameterMultipleInput
                #pmi = ParameterMultipleInput()
                #pmi.setParameterValue(paramValue)
                #paramValue = pmi
                if DEV_INFO: print "#####################################################################"
                return paramValue

    def __defineParameters_raster2sextante(self, param, paramValue):
                if isinstance(paramValue, str):
                    layer = gvsig.currentView().getLayer(paramValue)
                    paramValue = self.__createSextanteRaster(layer)
                else:
                    paramValue = self.__createSextanteRaster(paramValue)

                if DEV_INFO: print "** extent add+"
                if self.__defaultAE == None:
                    self.__defaultAE = AnalysisExtent(paramValue)
                else:
                    self.__defaultAE.addExtent(AnalysisExtent(paramValue))
                return paramValue

    def __defineParameters_table2sextante(self, param, paramValue):
                if isinstance(paramValue, str):
                    layer = gvsig.currentProject().getTable(paramValue)
                    paramValue = self.__createSextanteTable(layer())
                else:
                    paramValue = self.__createSextanteTable(paramValue())
                return paramValue

    def __defineParameters(self, algorithm, kwparams):
        """ Define input parameters """
        params = algorithm.getParameters()
        if DEV_INFO: print self.__defaultAE

        for i in xrange(0,params.getNumberOfParameters()):
            param = params.getParameter(i)
            if DEV_INFO: print "****************************************** PARAMETER *******************************************"
            #print "********************* ", dir(param)
            #print "********************* ", type(param)
            #print "********************* ", param.getParameterName()
            #print "********************* ", param.getParameterDescription()
            #print "********************* ", param.getParameterTypeName()
            #print "********************* ", param.getParameterTooltip()
            #print "********************* ", param.getParameterClass()
            #print "********************* ", param.getClass()
            #print "********************* ", param.parameterName
            #print "********************* ", param.parameterTypeName
            paramValue = self.__defineParameters_str2value( i, param, kwparams)
            #print type(paramValue)

            #Vector to SEXTANTE
            if DEV_INFO: print  "PARAMETER TYPE: ",param.getParameterTypeName()
            if param.getParameterTypeName() == "Vector Layer":
                paramValue = self.__defineParameters_vector2sextante(param, paramValue)

            # Multiple input: Vector and Raster
            elif param.getParameterTypeName() == "Multiple Input": #para vectores y raster
                paramValue = self.__defineParameters_multi2sextante(param, paramValue)
            #Raster to SEXTANTE
            elif param.getParameterTypeName() == "Raster Layer":
                paramValue = self.__defineParameters_raster2sextante(param, paramValue)
            #Table to SEXTANTE
            elif param.getParameterTypeName() == "Table":
                paramValue = self.__defineParameters_table2sextante(param, paramValue)
            #Set parameter value
            #print  "@@@@@@@@@@@@@@@@@@@@@@@@ cluster error: ", paramValue, type(paramValue)
            #print "@@@@@@@@@@@@@@@@@@@@@@@@ ", type(param)

            param.setParameterValue(paramValue)
            #print "@@@@@@@@@@@@@@", dir(param)

            #print "@@@@@@@@@@@@@@", param.isParameterValueCorrect()
            #print "@@@@@@@@@@@@@@ param:", param
            #print "@@@@@@@@@@@@@@ ", param.getParameterValueAsArrayList()


    def __defineExtent(self, algorithm, kwparams):
        """ Define Analysis Extent """
        if self.__defaultAE == None:
            if DEV_INFO: print "-------- cambiar extent"
            change=True
        else:
            if DEV_INFO: print "-------- no cambiar extent"
            change = False
            AExtent = self.__defaultAE
        changeCell = False
        if 'EXTENT' in kwparams.keys() and algorithm.getUserCanDefineAnalysisExtent() :
            changeCell = True
            frame = kwparams['EXTENT']
            if isinstance(frame, str): frame = gvsig.currentView().getLayer(frame)
            #print ("|"+str(frame)+"||"+str(type(frame)))
            if isinstance(frame, str) or isinstance(frame, DefaultViewDocument):
                AExtent = AnalysisExtent()
                if DEV_INFO: print "| EXTENT from VIEW"
                if isinstance(frame, DefaultViewDocument): view = frame
                else: view = gvsig.currentProject().getView(frame)
                envelope = view.getMap().getFullEnvelope()
                xlow = envelope.getLowerCorner().getX()
                ylow = envelope.getLowerCorner().getY()
                xup = envelope.getUpperCorner().getX()
                yup = envelope.getUpperCorner().getY()
                AExtent.setXRange(xlow, xup, False)
                AExtent.setYRange(ylow, yup, False)
                AExtent.setZRange(0, 0, False)
            elif isinstance(frame, DefaultFLyrRaster):
                if DEV_INFO: print "| EXTENT from RASTER"
                layer = self.__createSextanteRaster(frame)
                AExtent = AnalysisExtent(layer)
                changeCell = False
                #AExtent.setZRange(0, 1, True)
                if DEV_INFO: print AExtent
            elif isinstance(frame, list):
                if DEV_INFO: print "| EXTENT from LIST"
                AExtent = AnalysisExtent()
                AExtent.setCellSize(0.49)
                AExtent.setCellSizeZ(0.49)
                xlow, ylow, zlow, xup, yup, zup  = frame[0], frame[1], frame[2], frame[3], frame[4], frame[5]
                AExtent.setXRange(xlow, xup, True)
                AExtent.setYRange(ylow, yup, True)
                AExtent.setZRange(zlow, zup, True)
            elif isinstance(frame, FLayer):
                if DEV_INFO: print "| EXTENT from Layer"
                layer = self.__createSextanteLayer(frame())
                AExtent = AnalysisExtent(layer)
            else:
                raise Exception("Not Extent Define")
            algorithm.setAnalysisExtent(AExtent)

        elif change == True:
            if DEV_INFO: print ("| Not Extent: No input data")
            AExtent = AnalysisExtent()
            changeCell = True
            if self.__defaultAE != None:
                if DEV_INFO: print "| Extent from Algorithm Layers"
                AExtent = self.__defaultAE
            else:
                try:
                    if DEV_INFO: print "| Extent from View"
                    envelope = gvsig.currentView().getMap().getFullEnvelope()
                except:
                    raise Exception("None open View")

                if DEV_INFO: print "| Setting AExtent: ",
                try: #from view
                    xlow = envelope.getLowerCorner().getX()
                    ylow = envelope.getLowerCorner().getY()
                    zlow = 0
                    xup = envelope.getUpperCorner().getX()
                    yup = envelope.getUpperCorner().getY()
                    zup = 0
                    if DEV_INFO: print "| View: ",
                    if DEV_INFO: print xlow, ylow, xup,yup
                except: # default
                    xlow, ylow, zlow, xup, yup, zup = 0,0,0,100,100,0
                    if DEV_INFO: print "| Default:", xlow, ylow, xup, yup

                frame = Rectangle2D.Double(xlow, ylow, xup, yup)
                AExtent.setXRange(xlow, xup, False)
                AExtent.setYRange(ylow, yup, False)
                AExtent.setZRange(zlow, zup, False)
            algorithm.setAnalysisExtent(AExtent)

        #Set: cellsize
        if 'CELLSIZE' in kwparams.keys():
            AExtent.setCellSize(kwparams['CELLSIZE'])
            if DEV_INFO: print "| New Cellsize: ", kwparams['CELLSIZE'], AExtent.getCellSize()
        elif changeCell == True:
            AExtent.setCellSize(AExtent.getCellSize())
            if DEV_INFO: print "| Cellsize: ", AExtent.getCellSize()

        if 'CELLSIZEZ' in kwparams.keys():
            AExtent.setCellSizeZ(kwparams['CELLSIZEZ'])
            if DEV_INFO: print "| New Cellsize Z: ", kwparams['CELLSIZEZ'], AExtent.getCellSizeZ()
        elif changeCell == True:
            AExtent.setCellSize(AExtent.getCellSizeZ())
            if DEV_INFO: print "| CellsizeZ: ", AExtent.getCellSizeZ()

        if DEV_INFO: print "end extent: ", AExtent
        #AExtent.setZRange(0.0, 0.0, True)
        algorithm.setAnalysisExtent(AExtent)
        if DEV_INFO: print ("| Set Extent")

    def __defineOutput(self, algorithm, kwparams):
      if 'PATH' in kwparams.keys():
          path = kwparams['PATH']
          checkFilesExist(path)
          outputSet = algorithm.getOutputObjects()
          if outputSet.getOutputDataObjectsCount() == 1:
              out1 = outputSet.getOutput(0)
              out1.setOutputChannel(FileOutputChannel("New_name"))
              out1channel = out1.getOutputChannel()
              if isinstance(path, str):
                  out1channel.setFilename(path)
              elif isinstance(path, list):
                  out1channel.setFilename(path[0])
              else:
                  raise Exception("No valid path")
              if DEV_INFO: print "| PATH: Good path"
          elif outputSet.getOutputDataObjectsCount() > 1 and isinstance(path, list):
              for n in xrange(0, outputSet.getOutputDataObjectsCount()):
                  out1 = outputSet.getOutput(n)
                  out1.setOutputChannel(FileOutputChannel("New_name"))
                  out1channel = out1.getOutputChannel()
                  out1channel.setFilename(path[n])
                  if DEV_INFO: print "| PATH: Good path"
          else:
              raise Exception("Bad path")

      elif algorithm.getOutputObjects().getOutput(0).getOutputChannel():
          output0 = algorithm.getOutputObjects().getOutput(0)
          out0 = output0.getOutputChannel()
          out0.setFilename(None)
          if DEV_INFO: print "| PATH: Without path"

    def __executeAlgorithm(self, algorithm):
      """Execute Algorithm"""
      #Check algorithm
      correctValues = algorithm.hasCorrectParameterValues()
      if DEV_INFO: print "| Parameter values:", correctValues
      if not correctValues: raise Exception("Not correct values")
      try:
          if DEV_INFO: print "| Pre-algorithm:", list(algorithm.algorithmAsCommandLineSentences)
      except:
          if DEV_INFO: print "| Not - algorithm"

      algorithm.execute( None, self.__outputFactory)
      print "| Algorithm:", list(algorithm.algorithmAsCommandLineSentences)

    def __getOutputObjects(self, algorithm):
      """Take outputObjets of the algorithm"""
      oos = algorithm.getOutputObjects()
      ret = dict()
      for i in xrange(0, oos.getOutputObjectsCount()):
        oo = oos.getOutput(i)
        value = oo.getOutputObject()
        if isinstance(value, FlyrVectIVectorLayer):
            if DEV_INFO: print "| Vector"
            store = value.getFeatureStore()
            layer = MapContextLocator.getMapContextManager().createLayer(value.getName(),store)
            store.dispose()
            ret[value.getName()] = layer
            layer.dispose()
        elif isinstance(value, IRasterLayer):
            if DEV_INFO: print "| Raster layer"
            value.postProcess()
            dalManager = DALLocator.getDataManager()
            mapContextManager = MapContextLocator.getMapContextManager()
            params = dalManager.createStoreParameters("Gdal Store")
            namefile = File(value.getFilename())
            params.setFile(namefile)
            dataStore = dalManager.createStore(params)
            layer = mapContextManager.createLayer(value.getName(), dataStore)
            ret[value.getName()] = layer
        else:
            try:
                ret[value.getName()] = value
            except:
                if not value == None:
                    x = 0
                    while True:
                        field = "value_" + str(x)
                        if any(field in s for s in ret.keys()):
                            x += 1
                        ret[str(x)] = value
                        break
      return ret


    def __applyOutputLoadParameters(self, layer, kwparams):

        # Filtro
        if "OUTPUT_FILTER" in kwparams:
            if kwparams["OUTPUT_FILTER"] in layer.getName():
                pass
            else:
                print "|| Params filter: ", kwparams["OUTPUT_FILTER"], " goes out"
                return None

        # Name of the output layer
        if "NAME" in kwparams:
            layer.setName((kwparams["NAME"]).decode("UTF-8"))
        elif "TOCNAME" in kwparams:
            layer.setName((kwparams["TOCNAME"]).decode("UTF-8"))
        else:
            layer.setName(layer.getName())

        # Add layer or not
        if "ADDLAYER" in kwparams:
            if kwparams["ADDLAYER"]==True:
                addlayer = True
            elif kwparams["ADDLAYER"]==False:
                addlayer = False
        else:
            addlayer = True #Default for add results

        # Where to add it
        if "OUTPUT_VIEW" in kwparams:
            outputview = (kwparams["OUTPUT_VIEW"]).decode("UTF-8")
            if isinstance(outputview, str):
                view = currentProject().getView(outputview)
            else:
                view = outputview
        else:
            view = gvsig.currentView()

        # Active
        if "VISIBLE" in kwparams:
            visible = kwparams["VISIBLE"]
        else:
            visible = True

        if addlayer==True:
            view.addLayer(layer)
        return layer

    def __applyOutputLoadParametersVectorial(self, layer, kwparams):

        # Filtro
        if "OUTPUT_FILTER" in kwparams:
            if kwparams["OUTPUT_FILTER"] in layer.getName():
                pass
            else:
                print "|| Params filter: ", kwparams["OUTPUT_FILTER"], " goes out"
                return


        # Add layer or not
        if "ADDLAYER" in kwparams:
            if kwparams["ADDLAYER"]==True:
                addlayer = True
            elif kwparams["ADDLAYER"]==False:
                addlayer = False
        else:
            addlayer = True #Default for add results

        # Where to add it
        if "OUTPUT_VIEW" in kwparams:
            outputview = (kwparams["OUTPUT_VIEW"]).decode("UTF-8")
            if isinstance(outputview, str):
                view = currentProject().getView(outputview)
            else:
                view = outputview
        else:
            view = gvsig.currentView()

        # Active
        if "VISIBLE" in kwparams:
            visible = kwparams["VISIBLE"]
        else:
            visible = True

        parameters = {}
        shpFile = layer.getFeatureStore().getFullName()
        parametersshp = layer.getFeatureStore().getParameters()
        parameters["CRS"] = gvsig.currentView().getProjectionCode()
        parameters["shpFile"]= shpFile #parametersshp.getSHPFileName()
        layer = gvsig.loadLayer("Shape", **parameters)

        #layer = loadLayer(layer.getFeatureStore().getFullName())
        if addlayer==True:
            # Name of the output layer
            if "NAME" in kwparams:
                print "set name"
                layer.setName((kwparams["NAME"]).decode("UTF-8"))
            elif "TOCNAME" in kwparams:
                layer.setName((kwparams["TOCNAME"]).decode("UTF-8"))
            else:
                layer.setName(layer.getName())
            view.addLayer(layer)
        return layer

    def __returnOutputObjects(self, r, kwparams):
        if r == None: return
        outList = []
        print "| Output layers: "
        for value in r.values():
            if isinstance(value, unicode):
                outList.append(value.encode("UTF-8"))
                continue
            elif isinstance(value, FLyrVect):
                """

                parameters = {}

                parametersshp = value.getFeatureStore().getParameters()
                try:
                    parameters["CRS"] = parametersshp.getCRS()
                except:
                    parameters["CRS"] = gvsig.currentView().getProjectionCode()
                shpFile = value.getFeatureStore().getFullName()
                parameters["shpFile"]= shpFile
                layer = gvsig.loadLayer("Shape", **parameters)

                """

                print "|\t Value:", value.getName().encode("UTF-8")
                path = value.getDataStore().getFullName()
                print "|\t\tPath: ", path

                resultLyr = self.__applyOutputLoadParametersVectorial(value, kwparams)

                if resultLyr!=None:
                    outList.append(resultLyr)

            elif isinstance(value, FLayer):
                print "|\t Value:", value.getName()
                print "|\t\t", value.getFile()
                value = self.__applyOutputLoadParameters(value, kwparams)
                if value!=None:
                    outList.append(value)
            else:
                print "|\t Non-type \tValue: ", value
                continue

        #Return object or list
        print "\n"
        print "OUTLIST: ", outList
        if len(outList) > 1: return outList
        elif len(outList) == 1: return outList[0]
        else: return None


    def execute(self, algorithmId, kwparams):
      """ Execute algorithm """
      print "| Algoritmo: ", algorithmId

      algorithm = self.getAlgorithms()[algorithmId]
      #print algorithm.getAlgorithmAsCommandLineSentences()

      #Input params
      self.__defineParameters(algorithm, kwparams)

      #Analisys Extension
      self.__defineExtent(algorithm, kwparams)

      #Output files
      self.__defineOutput(algorithm, kwparams)

      #Exec algorithm
      self.__executeAlgorithm(algorithm)

      #Output objects
      ret = self.__getOutputObjects(algorithm)
      r = self.__returnOutputObjects(ret, kwparams)

      return r

def runalg(algorithmId,*params, **kwparams):
    for i in range(0,len(params)):
      kwparams[i]=params[i]

    geoprocess = Geoprocess()
    r = geoprocess.execute(algorithmId, kwparams)
    del(geoprocess)
    return r

def algHelp(geoalgorithmId):
    geoprocess = Geoprocess()
    for algorithmId, algorithm in geoprocess.getAlgorithms().items():
        if algorithmId.encode('UTF-8') == geoalgorithmId.encode('UTF-8') or geoalgorithmId == "All":
            pass
        else:
            continue
        print "* Algorithm help: ", algorithm.getName().encode('UTF-8')
        print "*", algorithm.commandLineHelp.encode('UTF-8')
    del(geoprocess)

def algSearch(strSearch):
    print "\nInicio de busqueda.."
    geoprocess = Geoprocess()
    search = strSearch.lower().encode('ASCII','ignore')
    for algorithmId, algorithm in geoprocess.getAlgorithms().items():
        name = (algorithm.getName()).lower().encode('ASCII','ignore')
        group = (algorithm.getGroup()).lower().encode('ASCII','ignore')
        con1 = str(name).find(search) >= 0
        con2 = str(group).find(search) >= 0
        con3 = algorithmId.encode('ASCII').find(search) >= 0
        if con1 or con2 or con3:
            if con1 or con2:
                print "ID: ", algorithmId, " || GROUP: ", algorithm.getGroup().encode('UTF-8'), " || NAME: ", algorithm.getName().encode('UTF-8')
            else:
                print "*", algorithm.commandLineHelp.encode('UTF-8')
    print "..Busqueda finalizada\n"
    del(geoprocess)

def getProjectLayer(view,layer):
    """Get vector layer or raster"""

    try:
        if isinstance(view, str): view = gvsig.currentProject().getView(view)
        if isinstance(layer, str):
            return view.getLayer(layer)
        else:
            return layer
    except: #Bug: Raster problem with getLayer
        for i in gvsig.currentProject().getView(view).getLayers():
            if i.name == layer: return i

def getProjectTable(table):
    """Get table"""
    return gvsig.currentProject().getTable(table)

def checkFilesExist(files):
    """Path or Paths of files"""
    #raise a exception

    if isinstance(files, str):
        if os.path.isfile(files): raise Exception("File already exist" + files)
    elif isinstance(files, list):
        for fname in files:
            if os.path.isfile(fname): raise Exception("File already exist" + fname)


###
### MODEL TO SCRIPT
###


def model2script(pathXML, pathFile):
    #eliminar la ultima linea
    #pathXML = commonsdialog.openFileDialog("Selecciona archivo", 'C:/gsoc/')
    #pathXML = str(pathXML[0])
    #pathXML = 'C:/gsoc/test02.model'
    #pathFILE = 'C:/gsoc/script0002.py'
    import os.path
    if os.path.isfile(pathXML)==True:
        pass
    else:
        print "No valid model file path"
        return
    fileFile = open(pathXML, 'r')
    document = fileFile.read()
    import xml.dom.minidom
    root = xml.dom.minidom.parseString(document)
    #root
    inputObject = {}
    inputObjectParams = {}
    dataObject = {}
    algorithms = {}
    tab = "    "
    gvpyFile = open(pathFile, "w")
    #Cargamos los parametros
    print "\nData object"
    for child in root.getElementsByTagName("data_object"):
        #data_object - Parametros
        if "INNER" in child.getAttribute("key"):
            inputObjectParams[child.getAttribute("key")] = child.getAttribute("value")
        #data_object - result of algorithms
        else:
            inputObject[child.getAttribute("key")]=[child.getAttribute("value"), child.getAttribute("description").encode("UTF-8")]

    print "\n Attribute"
    for child in root.getElementsByTagName("input"):
        for i in child.getElementsByTagName("attribute"):
                if i.getAttribute("name")=="default": dataObject[child.getAttribute("name")] = i.getAttribute("value")

    print "\n Algorithm"
    order = 1
    for child in reversed(root.getElementsByTagName("algorithm")):
        print "Algoritmo: ", child
        keyAlgorithm = child.getAttribute("key")
        algorithmParams = {}
        algorithmParams["alg_cmd_line_name"]=child.getAttribute("alg_cmd_line_name")
        for i in child.getElementsByTagName("assignment"):
            algorithmParams[i.getAttribute("key")] = i.getAttribute("assigned_to")
        algorithmParams["result_of_algorithm"] = keyAlgorithm
        algorithms[order] = algorithmParams
        order +=1

    print "\n\n******* RESULTADO *******"
    print "inputObject: ", inputObject
    print "inputObjectParams: ", inputObjectParams
    print "algorithms: ", algorithms
    print "data object: ", dataObject

    #Writing script .py
    print "\nTransform to gvpy"
    for i in root.getElementsByTagName("model"):
        modelName = i.getAttribute("name")
    gvpyFile.write("# Modelo de SEXTANTE: " + modelName)
    gvpyFile.write(
"""
import gvpy
import gvsig
import geom
import gvsig_raster

def main(*args):
""")

    print "gvpy - data_object"
    listInputObject = []
    for n in reversed(inputObject.keys()):
        listInputObject.append([n,inputObject[n][1]])

    print "gvpy - inputObjectParams"
    for n in (inputObjectParams.keys()):
        gvpyFile.write( tab + n + ' = "' + inputObjectParams[n] + '"\n' )

    print "gvpy - vars"
    for n in (dataObject.keys()):
        gvpyFile.write( tab + n +' = "' + dataObject[n] + '"\n\n' )


    print "gvpy - algorithms"
    #inputObject list of result algorithms names
    for n in reversed(sorted(algorithms.keys())): #reversed(algorithms.keys()):
        gvpy= ""
        alg = algorithms[n]
        #prefijo: buscar en los data_object el nombre que debe de llevar la capa resultado
        for i in listInputObject:
            if alg["result_of_algorithm"] in i[0]:
                prefix = i[0]
                description = i[1]
        #Escribimos el codigo del algoritmo
        gvpyFile.write( tab + '# '+ description + '\n')
        gvpy += prefix + '= gvpy.runalg("'+alg["alg_cmd_line_name"]+'"'
        for i in alg:
            if i == "alg_cmd_line_name" or i == "result_of_algorithm": continue
            gvpy += ', '+i+'='+ alg[i] + ''
        gvpy += ')'
        gvpyFile.write( tab + gvpy + "\n\n" )

    gvpyFile.close()

def main(*args):
    checkFilesExist("C:/gvsig/ran10.shp")
    r = runalg("generaterandomnormal", EXTENT = [0,0,0,500,500,0], MEAN =0.5, STDDEV = 0.5, ADDLAYER=False)
    #runalg("cluster" , INPUT=[(layer1, 0),(layer2,0)] , NUMCLASS=3)#, CELLSIZE=layer1.getCellSize(), CELLSIZEZ=1)#,EXTENT=layer1)
    #runalg("mergegrids", [layer1, layer2], "0")
    #v1 = runalg("randomvector",10, TYPE_POINT, EXTENT=[0,0,0,500,500,0], NAME="Random vector")

    #r = runalg("generaterandomnormal", EXTENT = [0,0,0,500,500,0], MEAN =0.5, STDDEV = 0.5)

    pass


