#!/usr/bin/env python

#  Copyright (C) 2010 Simon Wood
#  Copyright (C) 2010 Hazen Babcock
#  Copyright (C) 2010-2016 Alan W. Irwin

#  Simple amalgamated demo of plsmem and plsmema under Python for the
#  mem, memcairo, and memqt devices.
#
#  This file is part of PLplot.
#
#  PLplot is free software; you can redistribute it and/or modify
#  it under the terms of the GNU Library General Public License as published
#  by the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  PLplot is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Library General Public License for more details.
#
#  You should have received a copy of the GNU Library General Public License
#  along with PLplot; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#

from PIL import Image
import math
import numpy.numarray

from plplot_python_start import *

import plplot as w

def plot(w, device_name, ifRGBA, width, height, my_buffer, x, y, data, max_val):
    if ifRGBA:
        colour_code = "RGBA"
        # initialise for mem-style RGBA device
        w.plsmema(width,height,my_buffer)
    else:
        colour_code = "RGB"
        # initialise for mem-style RGB device
        w.plsmem(width,height,my_buffer)

    w.plstart (device_name, 1, 1);

    w.plcol0(2)
    w.plenv(0, 360, 0, 90, 0, 2)
    w.plcol0(2)
    w.pllab("Azimuth", "Elevation", "Rectangular Sky View with " + colour_code + " " + device_name + " device")

    # plot binned density
    w.plimage(data, 0, 360, 0, 90, 0, max_val, 0, 360, 0, 90)

    # plot points
    w.plpoin(x,y,5)

    # have to finish plotting so that the plot data gets transferred
    # back from the cairo working surface to the user supplied memory.
    w.plend1()

    # Use fromstring as frombuffer will invert the image
    my_image = Image.fromstring(colour_code, (width,height), my_buffer)
    my_image.save(device_name + "_" + colour_code + ".png")

# ---------------------------------------------------
# Build random array (aka fake data)

w.plseed(1234)
x=[]
y=[]

for i in range(500) :
    x.append(w.plrandd() * 360)
    y.append(w.plrandd() * 90)

# compute binned density on 15' boundaries
# 360' gives 24 divisions
# 90' gives 6 divisions

width = 24
height = 6

max_val = 0
data = numpy.numarray.zeros((width,height))

for i in range(len(x)):
    data[int(x[i]/(360/width))][int(y[i]/(90/height))] += 1
    if data[int(x[i]/(360/width))][int(y[i]/(90/height))] > max_val:
        max_val +=1

# ---------------------------------------------------
# Initialise buffer

# Start from a blank canvas
width = 480
height = 320

# Dark gray background (necessarily opaque for RGB format).
background = numpy.numarray.zeros(3, numpy.uint8) + 30
my_buffer = numpy.numarray.zeros((height,width,3), numpy.uint8) + background

# Dark gray semi-transparent background.
background = numpy.numarray.zeros(4, numpy.uint8) + 30
background[3] = 200
my_buffera = numpy.numarray.zeros((height,width,4), numpy.uint8) + background

'''
# Or open an existing image
# (note 'asarray' will fail as it sees PIL image as an array already and
# does not perform a copy to make a writable array)
src_img = Image.open("input.png")
my_buffer = numpy.array(src_img.convert('RGB'), numpy.uint8)
(width, height) = src_img.size
'''

# Configured device_list depends on what w.plsmem and w.plsmema devices
# are available from the PLplot build.
device_list = ["mem", "memcairo", "memqt"]
for device_name in device_list:
    # plot writes on top of buffer each time so must use an independent (deep) copy.
    buffer = numpy.array(my_buffer,copy=True)
    plot(w, device_name, False, width, height, buffer, x, y, data, max_val)
    # "mem" device does not (yet) have RGBA capability.
    if device_name != "mem":
        buffer = numpy.array(my_buffera,copy=True)
        plot(w, device_name, True, width, height, buffer, x, y, data, max_val)
