

# Habilitamos el acceso a los plugins de geodb y del documento tabla
use_plugin("org.gvsig.app.document.table.app.mainplugin")
use_plugin("org.gvsig.geodb.app.mainplugin")

from gvsig import *
from commonsdialog import *

from gvsig.libs.formpanel import FormPanel

from java.awt import BorderLayout
from org.gvsig.fmap.dal import DALLocator
from org.gvsig.fmap.dal.store.jdbc import JDBCServerExplorerParameters
from org.gvsig.fmap.mapcontrol.dal.feature.swing.table import FeatureTableModel
from org.gvsig.fmap.mapcontrol.dal.feature.swing.table import ConfigurableFeatureTableModel
from org.gvsig.fmap.mapcontrol.dal.feature.swing import FeatureTablePanel
from org.gvsig.fmap.mapcontrol.dal.feature.swing import FeatureTable
from org.gvsig.app.project.documents.table import TableManager
from org.gvsig.fmap.mapcontext import MapContextLocator
from org.gvsig.geodb.vectorialdb.wizard import VectorialDBConnectionParamsDialog
from org.gvsig.fmap.geom import GeometryLocator
from org.gvsig.fmap.geom import Geometry

from org.fife.ui.rsyntaxtextarea import RSyntaxTextArea
from org.fife.ui.rsyntaxtextarea import SyntaxConstants
from org.fife.ui.rtextarea import RTextScrollPane


geom_types = (
  ( "GEOMETRY", Geometry.TYPES.GEOMETRY ),
  ( "POINT", Geometry.TYPES.POINT ),
  ( "LINE", Geometry.TYPES.LINE ),
  ( "POLYGON", Geometry.TYPES.POLYGON ),
  ( "MULTIPOINT", Geometry.TYPES.MULTIPOINT ),
  ( "MULTILINE", Geometry.TYPES.MULTICURVE ),
  ( "MULTIPOLYGON", Geometry.TYPES.MULTISURFACE )
)

geom_subtypes = (
  ( "2D", Geometry.SUBTYPES.GEOM2D ),
  ( "2DM", Geometry.SUBTYPES.GEOM2DM ),
  ( "3D", Geometry.SUBTYPES.GEOM3D ),
  ( "3DM", Geometry.SUBTYPES.GEOM3DM )
)


class SQLConsole(FormPanel):

  def __init__(self):
    FormPanel.__init__(self, script.getResource("sqlconsole.xml"))
    self.featureTable = None
    self.currentStore = None

    dataManager = DALLocator.getDataManager()
    pool = dataManager.getDataServerExplorerPool()
    for entry in pool.iterator():
      if isinstance(entry.getExplorerParameters(), JDBCServerExplorerParameters ) :
        self.cboBaseDeDatos.addItem(entry.getName())

    self.sqlContainer.setLayout(BorderLayout())
    self.sqlContainer.add(self.getSQLTextarea(), BorderLayout.CENTER)
    self.sqlContainer.updateUI()

    self.cboGeomType.addItem("")
    for geom_type in geom_types:
      self.cboGeomType.addItem(geom_type[0])

    self.cboGeomSubtype.addItem("")
    for geom_subtype in geom_subtypes:
      self.cboGeomSubtype.addItem(geom_subtype[0])


  def show(self):
    self.showWindow("SQL Console")

  def getExplorer(self):
    dataManager = DALLocator.getDataManager()
    pool = dataManager.getDataServerExplorerPool()
    name = self.cboBaseDeDatos.getSelectedItem()
    params = pool.get(name).getExplorerParameters()
    explorer = dataManager.openServerExplorer(params.getExplorerName(),params)
    return explorer

  def getMessageStack(self,ex):
    msgs = ""
    lastmsg = None
    while ex != None:
      msg = ex.getMessage()
      if msg!=None and lastmsg != msg:
        lastmsg = msg
        msgs += "\n - " + msg
      ex = ex.getCause()
    return msgs

  def getSQLTextarea(self):
    self.txtSQL = RSyntaxTextArea(6,30)
    self.txtSQL.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL)
    self.txtSQL.setCodeFoldingEnabled(True)
    self.txtSQL.setClearWhitespaceLinesEnabled(True)
    self.txtSQL.setAutoIndentEnabled(True)
    self.txtSQL.setCloseCurlyBraces(True)
    self.txtSQL.setWhitespaceVisible(True)
    self.txtSQL.setAnimateBracketMatching(True)
    self.txtSQL.setBracketMatchingEnabled(True)
    self.txtSQL.setAutoIndentEnabled(True)
    self.txtSQL.setTabsEmulated(True)
    self.txtSQL.setTabSize(2)
    self.txtSQL.setAntiAliasingEnabled(True)
    self.txtSQL.setText("select * from municipios_navarra")
    return  RTextScrollPane(self.txtSQL)


  def btnEjecutar_click(self, *args):
    explorer = self.getExplorer()
    openParams = explorer.getOpenParameters()
    openParams.setTable("--")
    openParams.setSQL(self.txtSQL.getText())
    try:
      self.currentStore = explorer.open(openParams)
    except Throwable, ex:
      self.txtMensajes.setText(self.getMessageStack(ex))
      if self.featureTable!=None:
        self.featureTable.setVisible(False)
      self.tabSalida.setSelectedIndex(1)
      self.currentStore = None
      return
    if self.featureTable == None:
      tablePanel = FeatureTablePanel(self.currentStore)
      self.tableContainer.setLayout(BorderLayout())
      self.tableContainer.add(tablePanel, BorderLayout.CENTER)
      self.featureTable = tablePanel.getTable()
      self.tableContainer.updateUI()
    else:
      tableModel = ConfigurableFeatureTableModel(self.currentStore, None)
      self.featureTable.setModel(tableModel)

    self.cboCampoGeometria.removeAllItems()
    self.cboClavePrimaria.removeAllItems()
    self.cboClavePrimaria.addItem("")

    columNames = list()
    ft = self.currentStore.getDefaultFeatureType()
    for at in ft.getAttributeDescriptors():
      name = at.getName()
      columNames.append(name)
      self.cboCampoGeometria.addItem(name)
      self.cboClavePrimaria.addItem(name)


    self.featureTable.getModel().setVisibleColumns(columNames)
    self.cboCampoGeometria.setSelectedItem(ft.getDefaultGeometryAttributeName())
    if not ft.getDefaultGeometryAttribute() in ("",None):
      gt = ft.getDefaultGeometryAttribute().getGeomType()
      n = 0
      for v in geom_types:
        if v[1] == gt.getType():
          self.cboGeomType.setSelectedIndex(n)
          break
        n+=1
      n = 0
      for v in geom_subtypes:
        if v[1] == gt.getSubType():
          self.cboGeomSubtype.setSelectedIndex(n+1)
          break
        n+=1

    self.txtMensajes.setText("")
    self.featureTable.setVisible(True)
    self.tabSalida.setSelectedIndex(0)


  def btnAdministrar_click(self, *args):
    dialog = VectorialDBConnectionParamsDialog()
    dialog.showDialog()

  def btnCargar_click(self, *args):
    cargarComo = str(self.cboCargarComo.getSelectedItem())
    if "tabla" in cargarComo.lower():
      application = ApplicationLocator.getManager()
      projectManager = application.getProjectManager()
      tableDoc = projectManager.createDocument(TableManager.TYPENAME)
      tableDoc.setStore(self.featureTable.getModel().getFeatureStore())
      name = inputbox("Nombre del documento tabla", "Nombre", QUESTION, "Sql")
      tableDoc.setName(name)
      project = application.getCurrentProject()
      project.addDocument(tableDoc)
    else:
      view = currentView()
      if view == None:
        msgbox("Debera haber una vista activa para realizar esta accion")
        return
      name = inputbox("Nombre de la capa", "Nombre", QUESTION, "Sql")
      layer = MapContextLocator.getMapContextManager().createLayer(
        name,
        self.featureTable.getModel().getFeatureStore()
      )
      layers = view.getMapContext().getLayers().addLayer(layer)


  def cboClavePrimaria_click(self, *args):
    name = self.cboClavePrimaria.getSelectedItem()
    if name in ("",None):
      return
    if self.currentStore == None:
      return
    ft = self.currentStore.getDefaultFeatureType().getEditable()
    attr = ft.get(name)
    if attr == None:
      print "???? no encuentro la descripcion del atributo '%s'." % name
      return
    attr.setIsPrimaryKey(True)
    self.currentStore.edit()
    self.currentStore.update(ft)
    self.currentStore.finishEditing()

  def getGeomTypeByName(self,name):
    for v in geom_types:
      if v[0].lower() == name.lower():
        return v[1]
    return Geometry.TYPES.GEOMETRY

  def getGeomSubtypeByName(self,name):
    for v in geom_subtypes:
      if v[0].lower() == name.lower():
        return v[1]
    return Geometry.SUBTYPES.GEOM2D

  def cboGeomType_click(self,*args):
    geom_type_name = self.cboGeomType.getSelectedItem()
    geom_subtype_name = self.cboGeomSubtype.getSelectedItem()
    if geom_type_name in ("",None):
      return
    geom_type = GeometryLocator.getGeometryManager().getGeometryType(
      self.getGeomTypeByName(geom_type_name),
      self.getGeomSubtypeByName(geom_subtype_name)
    )
    ft = self.currentStore.getDefaultFeatureType().getEditable()
    attr = ft.getDefaultGeometryAttribute()
    if attr == None:
      return
    attr.setGeometryType(geom_type)
    self.currentStore.edit()
    self.currentStore.update(ft)
    self.currentStore.finishEditing()

  def cboGeomSubtype_click(self,*args):
    self.cboGeomType_click(*args)


def main(*args):
  sqlconsole = SQLConsole()
  sqlconsole.show()

