
from gvsig import *
from gvsig.commonsdialog import *
from gvsig.libs.formpanel import FormPanel, getResource

import os
import os.path
import shutil
import sys
import subprocess
import threading
import logging


from java.awt import Dimension

from org.gvsig.scripting.swing.api import ScriptingSwingLocator

class MakeDocs(FormPanel, threading.Thread):
  def __init__(self,workspace,projects,outputfolder):
    threading.Thread.__init__(self)
    FormPanel.__init__(self, getResource(__file__,"makedocs.xml"))
    self.setName("Javadoc creator")
    self.setPreferredSize(700,230)
    self.canceled = False

    self.workspace = workspace
    self.projects = projects
    self.outputfolder = outputfolder
    self.txtWorkspace.setText(workspace)
    self.txtOutputFolder.setText(outputfolder)

  def findJavaSources(self,workspace,project):
    projectFolder = os.path.join(workspace,project)
    sources = list()
    for root, dirs, files in os.walk(projectFolder):
        for file in files:
            if file == "pom.xml":
              if root[-5:] != ".main":
                javaSources = os.path.join(root,"src","main","java")
                if os.path.isdir(javaSources):
                  sources.append(javaSources)
                  self.message2(root)
    return sources

  def findJavadocSources(self,workspace,projects):
    sources = list()
    for project, url in projects:
      sources.extend(self.findJavaSources(workspace,project))
      if project == "org.gvsig.scripting":
        sources.append(os.path.join(
          workspace,project,"org.gvsig.scripting.app","org.gvsig.scripting.app.mainplugin",
          "src","main","resources-plugin","scripting","lib","gvsig","javadocs"
        ))
    return sources

  def calculateCountFromSources(self,sources):
    countfiles = 0
    folders = set()
    for sourceFolder in sources:
      for root, dirs, files in os.walk(sourceFolder):
        for f in files:
            if f.endswith(".java"):
              countfiles+=1
              self.message2("[%05d] %s" %  (countfiles, os.path.join(root,f)))
        if len(files)>0:
          package = root[len(sourceFolder)+1:]
          folders.add(package)

    return countfiles, len(folders)

  def calculateHTMLFileList(self,htmlroot, listfname):
    listfile= open(listfname,"w")
    countfiles = 0
    for root, dirs, files in os.walk(htmlroot):
      for f in files:
        if f.startswith("package-"):
          continue
        if f.endswith(".html"):
          countfiles+=1
          listfile.write(os.path.join(root,f))
          listfile.write("\n")
          self.message2("[%05d] %s" %  (countfiles, os.path.join(root,f)))
    listfile.close()
    return countfiles

  def message(self,msg):
    self.lblStatus.setText(msg)

  def message2(self,msg):
    self.lblStatus2.setText(msg)

  def checkoutSources(self,workspace,projects, outputpath):
    if not os.path.exists(workspace):
      os.makedirs(workspace)
    self.message("Descargando proyectos...")
    count = 0
    self.pgbProgreso.setMaximum(len(projects))
    self.pgbProgreso.setValue(count)
    self.pgbProgreso.setIndeterminate(False)
    for project, url in projects:
      if self.canceled:
        break
      self.message2("Descargando %s..." % project)
      count += 1
      self.pgbProgreso.setValue(count)
      cmd = 'cd "%s" ; svn checkout "%s"' % (workspace,url)
      os.system(cmd)

  def mkjavadoc(self,workspace,projects, outputpath):
    try:
      self.pgbProgreso.setIndeterminate(True)
      self.message("Creando carpeta de salida...")
      if not os.path.exists(outputpath):
        os.makedirs(outputpath)

      os.chdir(outputpath)
      if not os.path.exists("html"):
        os.makedirs("html")
      os.chdir("html")

      if not self.canceled  and self.chkCheckoutSources.isSelected():
        self.checkoutSources(workspace,projects, outputpath)

      if not self.canceled  and self.chkGenerarJavadocs.isSelected():
        self.message("Eliminando javadoc existentes...")
        self.pgbProgreso.setIndeterminate(True)
        os.chdir("..")
        shutil.rmtree("html",True)
        os.makedirs("html")
        os.chdir("html")

        self.message("Localizando fuentes...")
        sources = self.findJavadocSources(workspace,projects)

        self.message("Preparando procesado...")
        maxfiles, maxpackages = self.calculateCountFromSources(sources)

        argsfile = file("javadoc_args","w")
        #argsfile.write("-nonavbar\n")
        argsfile.write("-link http://docs.oracle.com/javase/8/docs/api/\n")
        argsfile.write("-encoding ISO-8859-1\n")
        argsfile.write("-subpackages org:scripting\n")
        argsfile.write("-sourcepath ")
        for source in sources:
          argsfile.write(":%s" % source)
        argsfile.write("\n")
        argsfile.close()

        proc = subprocess.Popen(["javadoc", "@javadoc_args"], stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
        stdoutprocess = proc.stdout
        generatingcount = 0
        loadingcount=0

        self.pgbProgreso.setMaximum(maxpackages)
        self.pgbProgreso.setValue(0)
        self.pgbProgreso.setIndeterminate(False)

        for line in stdoutprocess:
          if self.canceled:
            break
          #print line[:-1]
          if ": error:" in line :
            self.message("Procesando fuentes...")
            self.message2(line)

          elif line.startswith("Generating "):
            self.message("Generando javadocs...")
            if generatingcount == 0:
              self.pgbProgreso.setMaximum(maxfiles + maxpackages*3 + 9)
            self.message2(line[11:-9])
            if "/package-" in line:
              generatingcount+=1
            else:
              if os.path.basename(line[:-4]).count(".")==1:
                generatingcount +=1
            self.pgbProgreso.setValue(generatingcount)

          elif line.startswith("Loading source files for package "):
            self.message("Cargando fuentes...")
            loadingcount+=1
            self.pgbProgreso.setValue(loadingcount)
            self.message2(line[33:])

      self.message("Proceso terminado")
      self.message2("")
      self.pgbProgreso.setValue(self.pgbProgreso.getMaximum())
      if self.canceled:
        print "Proceso cancelado"

    except Exception, ex:
      self.message("Proceso abortado")
      self.message2(str(ex))
      print str(ex)
      logging.exception("Proceso abortado")

  def btnSelectWorkspace_click(self, *args):
    f = openFolderDialog("Selecciona la carpeta del workspace")
    if f == None or len(f)<1:
      return
    self.txtWorkspace.setText(f[0].getAbsolutePath())

  def btnSelectOutputFolder_click(self, *args):
    f = openFolderDialog("Selecciona la carpeta de salida")
    if f == None or len(f)<1:
      return
    self.txtOutputFolder.setText(f[0].getAbsolutePath())

  def btnCerrar_click(self,*args):
    self.canceled = True
    self.hide()

  def btnProcesar_click(self,*args):
    self.btnProcesar.setEnabled(False)
    self.btnCerrar.setText("Cancelar")
    self.start()

  def showWindow(self,title="Crear javadocs"):
    windowManager = ScriptingSwingLocator.getUIManager()
    windowManager.showWindow(self.asJComponent(),title)

  def run(self):
    self.mkjavadoc(
      self.workspace,
      self.projects,
      self.outputfolder
    )
    # Falla al volverse a lanzar el proceso por que no se
    # a rearmado correctamente el thread. Asi que dejo
    # desactivado el boton.
    #self.btnProcesar.setEnabled(True)


def main(*args):
  workspace = "/tmp/makedocs"
  outputfolder = workspace + "/javadocs"
  projects = (
    ("org.gvsig.scripting","http://devel.gvsig.org/svn/gvsig-scripting/org.gvsig.scripting/trunk/org.gvsig.scripting"),
    ("org.gvsig.tools","http://devel.gvsig.org/svn/gvsig-tools/org.gvsig.tools/library/trunk/org.gvsig.tools"),
    ("org.gvsig.desktop","http://devel.gvsig.org/svn/gvsig-desktop/trunk/org.gvsig.desktop"),
    ("org.gvsig.gdal","http://devel.gvsig.org/svn/gvsig-gdal/trunk/org.gvsig.gdal"),
    ("org.gvsig.raster","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster/trunk/org.gvsig.raster"),
    ("org.gvsig.raster.gdal","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal"),
    ("org.gvsig.geoprocess","http://devel.gvsig.org/svn/gvsig-geoprocess/org.gvsig.geoprocess/trunk/org.gvsig.geoprocess"),
    ("org.gvsig.3d","http://devel.gvsig.org/svn/gvsig-3d/2.1/trunk/org.gvsig.view3d/"),
    ("org.gvsig.app.document.layout2.app","https://devel.gvsig.org/svn/gvsig-app-document-layout/trunk/org.gvsig.app.document.layout2.app"),
    ("org.gvsig.attributeeditor","http://devel.gvsig.org/svn/gvsig-attributeeditor/org.gvsig.attributeeditor/trunk/org.gvsig.attributeeditor"),
    ("org.gvsig.chart","http://devel.gvsig.org/svn/gvsig-basic-chart/org.gvsig.chart/trunk/org.gvsig.chart"),
    ("org.gvsig.complexlegend","http://devel.gvsig.org/svn/gvsig-base-legends/org.gvsig.complexlegend/trunk/org.gvsig.complexlegend"),
    ("org.gvsig.derivedgeometries","http://devel.gvsig.org/svn/gvsig-derived-geometries/org.gvsig.derivedgeometries/trunk/org.gvsig.derivedgeometries/"),
    ("org.gvsig.dgn","http://devel.gvsig.org/svn/gvsig-dgn/org.gvsig.dgn/trunk/org.gvsig.dgn"),
    ("org.gvsig.downloader","http://devel.gvsig.org/svn/gvsig-downloader/org.gvsig.downloader/trunk/org.gvsig.downloader/"),
    ("org.gvsig.dwg","http://devel.gvsig.org/svn/gvsig-dwg/trunk/org.gvsig.dwg/"),
    ("org.gvsig.dxf","http://devel.gvsig.org/svn/gvsig-dxf/org.gvsig.dxf/trunk/org.gvsig.dxf/"),
    ("org.gvsig.dyschromatopsia","http://devel.gvsig.org/svn/gvsig-dyschromatopsia/trunk/org.gvsig.dyschromatopsia/"),
    ("org.gvsig.educa.portableview","http://devel.gvsig.org/svn/gvsig-educa/org.gvsig.educa.portableview/trunk/org.gvsig.educa.portableview/"),
    ("org.gvsig.expressionfield","http://devel.gvsig.org/svn/gvsig-expression-field/org.gvsig.expressionfield/trunk/org.gvsig.expressionfield/"),
    ("org.gvsig.gpe","http://devel.gvsig.org/svn/gvsig-gpe/org.gvsig.gpe/library/trunk/org.gvsig.gpe/"),
    ("org.gvsig.hyperlink.app","http://devel.gvsig.org/svn/gvsig-hyperlink/org.gvsig.hyperlink.app/trunk/org.gvsig.hyperlink.app"),
    ("org.gvsig.jexcel","http://devel.gvsig.org/svn/gvsig-jexcel/org.gvsig.jexcel/trunk/org.gvsig.jexcel"),
    ("org.gvsig.jvmpreferences","http://devel.gvsig.org/svn/gvsig-projects-pool/org.gvsig.jvmpreferences/trunk/org.gvsig.jvmpreferences.native/"),
    ("org.gvsig.legend.dotdensity.app","http://devel.gvsig.org/svn/gvsig-base-legends/org.gvsig.legend.dotdensity.app.mainplugin/trunk/org.gvsig.legend.dotdensity.app.mainplugin/"),
    ("org.gvsig.legend.graduatedsymbols.app","http://devel.gvsig.org/svn/gvsig-base-legends/org.gvsig.legend.graduatedsymbols.app.mainplugin/trunk/org.gvsig.legend.graduatedsymbols.app.mainplugin/"),
    ("org.gvsig.legend.proportionalsymbols.app","http://devel.gvsig.org/svn/gvsig-base-legends/org.gvsig.legend.proportionalsymbols.app.mainplugin/trunk/org.gvsig.legend.proportionalsymbols.app.mainplugin/"),
    ("org.gvsig.legend.quantitybycategory.app","http://devel.gvsig.org/svn/gvsig-base-legends/org.gvsig.legend.quantitybycategory.app.mainplugin/trunk/org.gvsig.legend.quantitybycategory.app.mainplugin/"),
    ("org.gvsig.legend.vectorfilterexpression.app","http://devel.gvsig.org/svn/gvsig-base-legends/org.gvsig.legend.vectorfilterexpression.app.mainplugin/trunk/org.gvsig.legend.vectorfilterexpression.app.mainplugin/"),
    ("org.gvsig.mapsheets.app","http://devel.gvsig.org/svn/mapsheets/trunk/org.gvsig.mapsheets.app"),
    ("org.gvsig.postgresql","http://devel.gvsig.org/svn/gvsig-postgresql/trunk/org.gvsig.postgresql"),
    ("org.gvsig.projection.jcrs","http://devel.gvsig.org/svn/gvsig-jcrs/org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs"),
    ("org.gvsig.raster.ermapper","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.ermapper/trunk/org.gvsig.raster.ermapper/"),
    ("org.gvsig.raster.georeferencing","http://devel.gvsig.org/svn/gvsig-georeferencing/org.gvsig.raster.georeferencing/trunk/org.gvsig.raster.georeferencing/"),
    ("org.gvsig.raster.lizardtech","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.lizardtech/trunk/org.gvsig.raster.lizardtech/"),
    ("org.gvsig.raster.multifile","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.multifile/trunk/org.gvsig.raster.multifile/"),
    ("org.gvsig.raster.netcdf","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.netcdf/trunk/org.gvsig.raster.netcdf/"),
    ("org.gvsig.raster.osm","http://devel.gvsig.org/svn/gvsig-osm/org.gvsig.raster.osm/trunk/org.gvsig.raster.osm"),
    ("org.gvsig.raster.postgis","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.postgis/trunk/org.gvsig.raster.postgis/"),
    ("org.gvsig.raster.principalcomponents","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.principalcomponents/trunk/org.gvsig.raster.principalcomponents/"),
    ("org.gvsig.raster.reproject","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.reproject/trunk/org.gvsig.raster.reproject/"),
    ("org.gvsig.raster.roimask","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.roimask/trunk/org.gvsig.raster.roimask/"),
    ("org.gvsig.raster.tasseledcap","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.tasseledcap/trunk/org.gvsig.raster.tasseledcap/"),
    ("org.gvsig.raster.tilecache","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.tilecache/trunk/org.gvsig.raster.tilecache/"),
    ("org.gvsig.raster.tools","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.tools/trunk/org.gvsig.raster.tools/"),
    ("org.gvsig.raster.wms","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wms/trunk/org.gvsig.raster.wms/"),
    ("org.gvsig.raster.wcs","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wcs/trunk/org.gvsig.raster.wcs/"),
    ("org.gvsig.raster.wmts","http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wmts/trunk/org.gvsig.raster.wmts"),
    ("org.gvsig.seismic","http://devel.gvsig.org/svn/gvsig-seismic/org.gvsig.seismic/trunk/org.gvsig.seismic"),
    ("org.gvsig.sld","http://devel.gvsig.org/svn/gvsig-sldtools/org.gvsig.sld/trunk/org.gvsig.sld"),
    ("org.gvsig.vectorediting","http://devel.gvsig.org/svn/gvsig-vectorediting/org.gvsig.vectorediting/trunk/org.gvsig.vectorediting/"),
    ("org.gvsig.vectorediting.symmetry","http://devel.gvsig.org/svn/gvsig-vectorediting/org.gvsig.vectorediting.symmetry/trunk/org.gvsig.vectorediting.symmetry/"),
    ("org.gvsig.vectorediting.offset","http://devel.gvsig.org/svn/gvsig-vectorediting/org.gvsig.vectorediting.offset/trunk/org.gvsig.vectorediting.offset/"),
    ("org.gvsig.wfs.app","http://devel.gvsig.org/svn/gvsig-wfs/org.gvsig.wfs.app/trunk/org.gvsig.wfs.app/"),
    ("org.gvsig.customize.app","http://devel.gvsig.org/svn/gvsig-desktop-customize/trunk/org.gvsig.customize.app/"),
    ("org.gvsig.catalog","http://devel.gvsig.org/svn/gvsig-catalog/org.gvsig.catalog/trunk/org.gvsig.catalog/"),
    ("org.gvsig.gazetteer","http://devel.gvsig.org/svn/gvsig-gazetteer/org.gvsig.gazetteer/trunk/org.gvsig.gazetteer/"),
    ("org.gvsig.publish","http://devel.gvsig.org/svn/gvsig-publish/org.gvsig.publish/trunk/org.gvsig.publish"),
    ("org.gvsig.webmap","http://devel.gvsig.org/svn/gvsig-webmap/org.gvsig.webmap/trunk/org.gvsig.webmap"),
    ("org.gvsig.googlemaps","http://devel.gvsig.org/svn/gvsig-webmap/org.gvsig.googlemaps/trunk/org.gvsig.googlemaps"),
    ("org.gvsig.bingmaps","http://devel.gvsig.org/svn/gvsig-webmap/org.gvsig.bingmaps/trunk/org.gvsig.bingmaps"),
    ("org.gvsig.toolbox", "http://devel.gvsig.org/svn/gvsig-toolbox/org.gvsig.toolbox/trunk/org.gvsig.toolbox/"),
    ("org.gvsig.projection.api", "https://devel.gvsig.org/svn/gvsig-jcrs/org.gvsig.projection/trunk/org.gvsig.projection.api/"),
    ("org.gvsig.raster.cache", "http://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.cache/trunk/org.gvsig.raster.cache/"),
  )
  
  makedocs = MakeDocs(workspace,projects,outputfolder)
  makedocs.showWindow("Crear javadocs")
  #makedocs.run()

