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 = .8*(dist-mindist)/(maxdist-mindist) + .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()-.5, random.random() -.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()    
                


