import random, math
import os
from visual import *

os.chdir(r'P:\experim\conceptualmap')

weights = {}
distances = {}

fin = file('res_.txt')
matrix = [l.replace('\n', '').split(',') for l in fin.readlines()]
fin.close()

countries = matrix[0]
del matrix[0]

weightstab = [float(w) for w in matrix[0]]
del matrix[0]
maxweight = max(weightstab)
minweight = min(weightstab)

for country, weight in zip(countries, weightstab):
    weights[country] = 0.2 * weight / maxweight

dists = []
for y, line in zip(range(len(matrix)), matrix):
    for x, dist in zip(range(len(line)), line):
        if x == y:
            dist = 0.0
        else:
            dist = 0.1 - float(dist)
        distances[(countries[y], countries[x])] = dist

mindist = min(distances.values())
maxdist = max(distances.values())
print maxdist, mindist

tabel = {}
for y, line in zip(range(len(matrix)), matrix):
    for x, dist in zip(range(len(line)), line):
        dist = distances[(countries[y], countries[x])]
        dist = 0.8 * (dist - mindist) / (maxdist - mindist) + 0.1
        if dist < weights[countries[y]] + weights[countries[x]]:
            dist = weights[countries[y]] + weights[countries[x]]
        distances[(countries[y], countries[x])] = dist
        if x < y:
            tabel[(countries[y], countries[x])] = distances[(countries[y], countries[x])]
tabel = tabel.items()
tabel.sort(lambda a, b: cmp(b[1], a[1]))
# print "\n".join([str(l) for l in tabel] )


# create init positions

print 'we start'

balls = {}
curpos = {}
lastpos = {}
labels = {}
i = 0
for country in countries:
    curpos[country] = complex(random.random() - 0.5, random.random() - 0.5)
    lastpos[country] = curpos[country]
    balls[country] = sphere(
        pos=(curpos[country].imag, curpos[country].real, 2),
        radius=weights[country],
        color=color.hsv_to_rgb(((float(i) / len(countries)), 0.7, 0.7)),
    )
    labels[country] = label(
        pos=(curpos[country].imag, curpos[country].real, 2), text=country, box=0, height=8, opacity=0.2
    )

    i += 1


maxiter = 1000
laststress = 0.0
first = 1
while 1:
    totalstress = 0.0
    for count, fr in zip(range(len(countries)), countries):
        for to in countries[:count]:
            vector = lastpos[fr] - lastpos[to]
            dist = abs(vector)
            diff = dist - distances[(fr, to)]
            stress = diff * diff * weights[fr] * weights[to] / dist
            totalstress += stress
            if diff > 0:
                sign = 1
            else:
                sign = -1
            curpos[fr] += -sign * vector * stress
            curpos[to] += sign * vector * stress
            vector = curpos[fr] - curpos[to]
            if 0:  # push overlapping objects out of each others way
                dist = abs(vector)
                if dist < weights[fr] + weights[to]:
                    vector = vector * (weights[fr] + weights[to]) / dist
                    centre = (curpos[fr] + curpos[to]) / 2
                    curpos[fr] = centre + vector / 2
                    curpos[to] = centre - vector / 2
            # if i==299: print fr, to, dist, stress
        balls[fr].x = curpos[fr].imag
        balls[fr].y = curpos[fr].real
        labels[fr].x = curpos[fr].imag
        labels[fr].y = curpos[fr].real
    travel = 0.0
    for country in countries:
        travel += abs(curpos[country] - lastpos[country])
        lastpos[country] = curpos[country]
    print travel
    if not first and travel < 0.001:
        break
    first = 0

    # if i==0 or i==299: print 'stress', abs(laststress-stress), travel
    laststress = stress

print 'ready'

f = file('stressflash.txt', 'w')

for c in countries:
    f.write('%s|%2.6f|%2.6f|%2.6f\n' % (c, curpos[c].imag, curpos[c].real, weights[c] / 5))

f.close()
