import joms.oms.Video

class ThumbnailService
{
  boolean transactional = false

  def grailsApplication

  def getThumbnail(String cacheDirPath, String thumbnailPrefix, int size, String mimeType,
                   String inputFilename, String entryId, String projectionType, boolean overwrite = false)
  {
    def outputFile = new File(
        cacheDirPath,
        "${thumbnailPrefix}.jpg"
    )

    def outputFileTemp = new File(
        cacheDirPath,
        "${thumbnailPrefix}.jpg.tmp"
    )

    def histogramStretchType = "linear_auto_min_max"

    // for now we only support imagespace thumbnails
    //
    if ( projectionType != "imagespace" )
    {
      projectionType = "imagespace"
    }

    /*
    def foo = [
        inputFilename: inputFilename,
        entryId: entryId,
        outputFileTemp: outputFileTemp,
        mimeType: mimeType,
        size: size,
        histogramFile: "",
        stretchTypeToUse: histogramStretchType,
        keepAspectFlag: true
    ]

    println foo
    */

    if ( !outputFile.exists() || overwrite )
    {
      def stretchTypeToUse = histogramStretchType
      if ( ThumbnailGenerator.writeImageSpaceThumbnail(
          inputFilename,
          entryId,
          outputFileTemp as String,
          mimeType,
          size, size,
          "", // use default
          stretchTypeToUse, true) )
      {
        if ( outputFileTemp.exists() )
        {
          outputFileTemp.renameTo(outputFile);
        }
      }
    }

    return outputFile
  }

  def getFrame(String cacheDirPath, String thumbnailPrefix, int size, String inputFilename, boolean overwrite = false)
  {
    Video video = new Video()

    def outputFile = new File(cacheDirPath, "${thumbnailPrefix}.jpg")


    if ( !outputFile.exists() || overwrite )
    {
      if ( video.open(inputFilename) )
      {
        video.nextFrame();
        video.writeCurrentFrameToFile(outputFile.absolutePath, size);
      }
    }

    return outputFile
  }

  public File getRasterEntryThumbnailFile(RasterEntry rasterEntry, Map params)
  {
    def projectionType = params.projectionType;
    RasterDataSet rasterDataSet = rasterEntry.rasterDataSet
    RasterFile rasterFile = RasterFile.findWhere(rasterDataSet: rasterDataSet, type: "main")
    def size = params.size?.toInteger()
    def mimeType = params?.mimeType ?: "image/jpeg"
    boolean overwrite = params.overwrite ?: false

    if ( !size )
    size = grailsApplication.config.thumbnail.defaultSize

    String cacheDirPath = grailsApplication.config.thumbnail.cacheDir
    String thumbnailPrefix = "${rasterEntry.id}-${size}-${projectionType}"

    File outputFile = this.getThumbnail(
        cacheDirPath,
        thumbnailPrefix,
        size,
        mimeType,
        rasterFile.name,
        rasterEntry.entryId,
        projectionType,
        overwrite
    )
    return outputFile
  }

  public File getVideoDataSetThumbnailFile(VideoDataSet videoDataSet, Map params)
  {
    VideoFile videoFile = VideoFile.findWhere(videoDataSet: videoDataSet, type: "main")
    def size = params.size?.toInteger() ?: grailsApplication.config.thumbnail.defaultSize
    String cacheDirPath = grailsApplication.config.thumbnail.cacheDir
    String thumbnailPrefix = "${videoDataSet.id}-${size}"
    boolean overwrite = params.overwrite ?: false
    File outputFile = this.getFrame(cacheDirPath, thumbnailPrefix, size, videoFile.name, overwrite)

    return outputFile
  }

  def pregenerateThumbnailsForRepository(Repository repository)
  {
    def projectionType = "imagespace"
    def mimeType = "image/jpeg"
    def rasterDataSets = RasterDataSet.findAllByRepository(repository)
    def videoDataSets = VideoDataSet.findAllByRepository(repository)

    [128, 512].each {size ->
      rasterDataSets.each {rasterDataSet ->
        def rasterEntries = RasterEntry.findAllByRasterDataSet(rasterDataSet)

        rasterEntries.each {rasterEntry ->

          if ( RasterEntryFile.findWhere(rasterEntry: rasterEntry, type: "overview") )
          {
            def params = [
                projectionType: projectionType,
                size: size,
                mimeType: mimeType,
                overwrite: true
            ]

            this.getRasterEntryThumbnailFile(rasterEntry, params)
          }
        }
      }

      videoDataSets.each {videoDataSet ->
        def params = [size: size, overwrite: true]
        this.getVideoDataSetThumbnailFile(videoDataSet, params)
      }
    }
  }

}