import sys
sys.path.append('../')

import CreativeQiskit

n = 2
alps = CreativeQiskit.random_mountain(n)

pos,prob = alps.get_mountain()
print('coordinates\n',pos)
print('\nprobabilities\n',prob)

n = 8
alps = CreativeQiskit.random_mountain(n)
alps.qc.h(alps.qr[0])

pos,prob = alps.get_mountain()

import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial import Voronoi, voronoi_plot_2d
import random

def plot_mountain(pos,prob,levels=[0.3,0.8,0.9],log=True,perturb=0.0):
    [sea,tree,snow] = levels
    coords = []
    Z = []
    for node in pos:
        coords.append( [pos[node][0]+(1-random.random())*perturb,pos[node][1]+(1-random.random())*perturb] )
        if log:
            Z.append(np.log(prob[node]))
        else:
            Z.append(prob[node])
    
    vor = Voronoi(coords)
        
    minZ = min(Z)
    maxZ = max(Z)
    # normalize chosen colormap
    colors = []
    for node in range(len(Z)):
        z = (Z[node]-minZ)/(maxZ-minZ)
        if levels:
            if z<sea:
                color = (0,0.5,1,1)
            elif z<tree:
                color = (1*(z-sea),1*(1-sea),1*(z-sea),1)
            elif z<snow:
                color = (0.7,0.7,0.7,1)
            else:
                color = (1,1,1,1)
        else:
            color = (z,z,z,1)
        colors.append(color)

    # plot Voronoi diagram, and fill finite regions with color mapped from speed value
    voronoi_plot_2d(vor, show_points=True, show_vertices=False, point_size=0, line_width=0.0)
    for r in range(len(vor.point_region)):
        region = vor.regions[vor.point_region[r]]
        if not -1 in region:
            polygon = [vor.vertices[i] for i in region]
            plt.fill(*zip(*polygon), color=colors[r])
    plt.savefig('outputs/islands.png',dpi=1000)
    plt.show()

pos,prob = alps.get_mountain(noisy=0.3)
plot_mountain(pos,prob)

from qiskit import IBMQ
IBMQ.load_accounts()

pos,prob = alps.get_mountain(noisy='ibmq_16_melbourne')
plot_mountain(pos,prob)

pos,prob = alps.get_mountain(noisy=0.3,method='rings')
plot_mountain(pos,prob,levels=[0.35,0.8,0.9])

pos,prob = alps.get_mountain(method='rings',new_data=False)
plot_mountain(pos,prob,levels=[0.35,0.8,0.9])

for j in range(n-1):
    alps.qc.cx(alps.qr[j],alps.qr[j+1])

pos,prob = alps.get_mountain()
plot_mountain(pos,prob)

pos,prob = alps.get_mountain(noisy=0.3)
plot_mountain(pos,prob)

plot_mountain(pos,prob,perturb=0.75)