#!/usr/bin/env python
###################################################
#
#    # van der Walt color filter
#    # python gimp plugin
#    # by paul taney
#    # paultaney@yahoo.com
#    
#    # Licensed under GPLv3
#    # see www.fsf.org for details
#
# installation:  put this file in
#    $HOME/.gimp-2.n/plug-ins
# then look for it under <Image>/Filters/Render/
###################################################

		
import numpy as np

from gimpfu import *  # imports the symbols gimp, pdb, register and main
import os, sys, string
import datetime
import Interpolate as ma



def getXML(dictionary):
        line2 = transformLine(dictionary["line"])
        form = string.Template("""\
<?xml version=\"1.0\"?>
<iedro>
    <!--  who  -->             
    <operator>$operator</operator>  
  
    <!--  where  -->             
    <location>$location</location>         
    <lat>$lat</lat>               
    <long>$long</long>      
       
    <!--  when  -->             
    <timestamp>$timestamp</timestamp>  
    <datestamp>$datestamp</datestamp>        
    <chartdate>$chartdate </chartdate>       

    <!--  what  -->             
    <workingdirectory>$workingdirectory</workingdirectory>
    <imagepath>$imagepath</imagepath>        
    <datfilename>$datfilename</datfilename>        
    <xmlfilename>$xmlfilename</xmlfilename>        

    <!--  coordinate transformation -->                     
    <width>$width</width>   <!-- in pixels -->             
    <height>$height</height>
    
    <time_units>$time_units</time_units>       
    <world_units>$world_units</world_units>
    <time_coord_min>$time_coord_min</time_coord_min>
    <time_coord_max>$time_coord_max</time_coord_max>
    <world_coord_min>$world_coord_min</world_coord_min>
    <world_coord_max>$world_coord_max</world_coord_max>

    <!-- color filter setting -->
    <bluemask_factor>$bluemask_factor</bluemask_factor>

    <!-- line -->
""")

        s = form.substitute(dictionary)
        s += '\n    <line>%r</line>\n' % (dictionary["line"])
        if dictionary["line2"]:
            s += '\n    <line2>%r</line2>\n' % (line2)
        s += "</iedro>"
        if 0: print s
        return s
			

def python_fu_vanderwalt(image, drawable, operator, location, lat, long,
	       thisdate, chartdate, imagefile, xmlfilename, phenomena,
	       time_units, world_units, time_min, time_max, world_min,
               world_max, bluemask_factor):
	
	[ width, height, channels ] = image.shape
	
	dictionary = {
		"operator":operator,
		"location":location,
		"lat":lat,
		"long":long,
		"thisdate":thisdate,
		"chartdate":chartdate,
		"imagefile":imagefile,
		"xmlfilename":xmlfilename,
		"phenomena":phenomena,
		"time_units":time_units,
		"world_units":world_units,
		"time_min":time_min,
		"time_max":time_max,
		"world_min":world_min,
		"world_max":world_max,
		"bluemask_factor":bluemask_factor,
		"line":[],
		"line2":[],
		"width": width,
		"height":height,
		"channels":channels,
		}
	
        image.undo_group_start()
        try:
                """Stefan van der Walt gave me this filter on the numpy mailing list"""
                f = bluemask_factor
                #pdb.gimp_message("calling vanderWalt with factor=%f" % f)
 		RED, GRN, BLU = 0, 1, 2
		bluemask = (image[...,BLU] > f*image[...,GRN]) & \
			   (image[...,BLU] > f*image[...,RED])
		
		# post it as a new_layer  xxx
		blue_layer = gimp.layer(bluemask, width, height, RGBA_IMAGE, 100, NORMAL_MODE)
		image.addlayer(blue_layer, 0)  # from python_fu_template_image
		gimp.delete(blue_layer)
		
		# Create a new display window for the given image.
		gimp.display(image)
		gimp.displays_flush()
		
	finally:
		img.undo_group_end()
 
	line = np.array(bluemask.nonzero()).swapaxes(0,1).tolist()
	
	if line:
                try:
                        line = ma.flip_Y(line)
                        line = ma.interpolate(line)
                        #line = ma.uniqify(line)
                        line = ma.scale(line, image.width, image.height,
                                        time_coord_min, time_coord_max,
                                        world_coord_min, world_coord_max)
                        dictionary["line2"] = line
                except:
                        pass  # for testing, you dont need Interpolate.py 
	else:
	    pdb.gimp_message("the line is empty")
	
	# write it all to XML file
	s = getXML(dictionary)
	FH = open(dictionary["xmlfilename"], 'w')
	FH.write(s)
	FH.close()
	pdb.gimp_message("wrote %s" % (dictionary["xmlfilename"]))

	
# register the plug-in with Gimp
register(
	"python-fu-vanderwalt",  # name
        "Extract blue line v0.1",  # blurb
        """Extract bluest pixels by selecting an active rectangle and setting a bluemask
        factor with the slider.  They will be written to the named XML file.""",
        "Paul Taney",  # author
        "Licensed under GPLv3",  # copyright
        "September 2008",  # date
        "<Image>/Filters/Render/", 
        "RGB*", # declares the image types handled. 
	[
	# (PF_STRING, "arg",      "The argument",    "default-value")
        (PF_IMAGE, "image", _("Input image"), None),
        (PF_DRAWABLE, "drawable", _("Input drawable"), None),
	(PF_TEXT,  "operator",    _("operator:"),    "Shem O. Wandiga"), 
	(PF_TEXT,  "location",    _("location:"),    "Otjikondo, Etosha NP, Zambia"),	
	(PF_TEXT,  "lat",    _("latitude:"),    "19deg54min South"),    	
	(PF_TEXT,  "long",   _("longitude:"),   "15deg40min East"),   	
	(PF_TEXT,  "thisdate",    _("this date:"),   "2008-09-20"),   	
	(PF_TEXT,  "chartdate",   _("chart date:"),  "2008-09-20"),  	
	(PF_FILENAME, "imagefile", _("image file:"), "8bitchart02_small.tiff"),   	
	(PF_FILENAME, "xmlfilename",   _("XML file:"),   "tmp.xml"),    	
	(PF_RADIO,  "phenomena",   _("phenomena:"),  "rainfall", (
		("_rainfall", "rainfall"), 
		("_temperature", "temperature"), 
		("_pressure", "pressure"))),   	
	(PF_RADIO, "time_units",   _("time units:"),  "hours", (
		("_hours", "hours"),
		("_days", "days"),
		("_weeks", "weeks"))), 	
	(PF_RADIO, "world_units",  _("world units:"), "inches" (
		("cm", "cm"), 
		("inches", "inches"), 
		("feet", "feet"), 	   
		("degrees F", "degrees F"),
		("degrees C", "degrees C"), 
		("hectopascals", "hectopascals"), 
		("millibars", "millibars"))),	
	(PF_INT,   "time_min",    	_("time min:"),    "0"),    	
	(PF_INT,   "time_max",    	_("time max:"),    "0"),    	
	(PF_INT,   "world_min",    _("world min:"),   "0"),    	
	(PF_INT,   "world_max",    _("world max:"),   "0"),    	
	(PF_SLIDER, "f",    _("bluemask factor:"),   1.4, (1.2, 1.7, .1)),
	],
	[],  # 3-tuples of the form (type, name, description), the return values for the function.
	"python_fu_vanderwalt")  # function
 
main()

# Notes:	

# If the plugin is to be run on an image,  the first parameter to the
# plugin function should be the image, and the second should be the current drawable 
# Any other parameters are specific to the plugin. -- James

# drawable.get_pixel_rgn(x, y, w, h, [dirty, [shadow])
# Creates a pixel region for the drawable. It will cover the region with
# origin (x,y) and dimensions w x h. The dirty argument sets whether any
# changes to the pixel region will be reflected in the drawable -- default
# is TRUE. The shadow argument sets whether the pixel region acts on the
# shadow tiles or not (default is FALSE). If you draw on the shadow tiles,
# you must call drawable.merge_shadow() for changes to take effect.