# for very small networks (~ 100 nodes)
# subdivide into subcommunities using the Girvan-Newman betweenness
# clustering algorithm
# you can either remove edges one at a time
# or keep removing them until a community is separated

import java
import javax.swing
import com

class gntool(com.hp.hpl.guess.ui.DockableAdapter):

	label = JLabel(" communities   ")
	label2 = JLabel("0 edges removed ")
	testButton = javax.swing.JButton("remove edge")
	breakButton = javax.swing.JButton("next breakup")

	numremoved = 0
	colors = []
	removededges = []
	prevnum = 0
	prevnumisolates = 0

	def __init__(self):
		setSynchronous(true)

		# add a betweenness property 'bet' to edges
		try:
			g.edges.bet = 0
		except (Error),e:
			addEdgeField("bet",Types.DOUBLE,0.0)

		self.testButton.actionPerformed = self.buttonPressed
		self.breakButton.actionPerformed = self.nextCommunity

		# add the label and slider to the UI
		self.add(self.label)
		self.add(self.label2)
		self.add(self.testButton)
		self.add(self.breakButton)

		# count the number of communities and the number of isolates
		numcommunities = 0
		numisolates = 0
		for i in range(100):
			self.colors.append(randomColor());
		tmp = weakComponentClusters()
		for c in tmp:
			if (c.__len__() > 1):
				numcommunities += 1
			else:
				numisolates += 1

		# if there is at least one community
		# draw convex hulls
		if (numcommunities > 0):
			hulls = getConvexHulls()
			for hull in hulls:
				removeConvexHull(hull)

			i = 0
			for c in tmp:
				if (c.__len__() > 1):
					i = i+1	
					createConvexHull(c,self.colors[i])
		self.prevnum = numcommunities
		self.prevnumisolates = numisolates
		self.label.setText(str(numcommunities)+" communities and "+str(numisolates)+" isolates")

		
		# calculate betweenness of all edges
		g.edges.betweenness
		for ed in g.edges:
			ed.bet = ed.betweenness

		# highlight the edge with highest betweenness in red
		(bet == bet.max).color=red

		# dock the new panel into the UI
		ui.dock(self)

	def buttonPressed(self,event):
		# remove highest betweenness edge

		tmp=(bet==bet.max)
		for ed in tmp:
			removeEdge(ed)
			self.numremoved += 1

		g.edges.betweenness
		for ed in g.edges:
			ed.bet = ed.betweenness

		(bet == bet.max).color=red

		numcommunities = 0
		numisolates = 0
		tmp = weakComponentClusters()
		for c in tmp:
			if (c.__len__() > 1):
				numcommunities += 1
			else:
				numisolates += 1
	
		self.label.setText(str(numcommunities)+" communities and "+str(numisolates)+" isolates")

		self.label2.setText(str(self.numremoved)+" edges removed")


		if ((self.prevnum != numcommunities)|(self.prevnumisolates != numisolates)):
			hulls = getConvexHulls()
			for hull in hulls:
				removeConvexHull(hull)

			i = 0
			for c in tmp:
				if (c.__len__() > 1):
					i = i+1	
					createConvexHull(c,self.colors[i])

		self.prevnum = numcommunities
		self.prevnumisolates = numisolates

	def nextCommunity(self,event):
		# remove edges until a new community shakes out

		while (1):
			tmp=(bet==bet.max)
			for ed in tmp:
				self.removededges.append(ed)
				removeEdge(ed)
				self.numremoved += 1

			g.edges.betweenness
			for ed in g.edges:
				ed.bet = ed.betweenness

			(bet == bet.max).color=red

			numcommunities = 0
			numisolates = 0
			tmp = weakComponentClusters()
			for c in tmp:
				if (c.__len__() > 1):
					numcommunities += 1
				else:
					numisolates += 1
	
			self.label.setText(str(numcommunities)+" communities and "+str(numisolates)+" isolates")

			self.label2.setText(str(self.numremoved)+" edges removed")


			if ((self.prevnum != numcommunities)|(self.prevnumisolates != numisolates)):
				hulls = getConvexHulls()
				for hull in hulls:
					removeConvexHull(hull)

				i = 0
				for c in tmp:
					if (c.__len__() > 1):
						i = i+1	
						createConvexHull(c,self.colors[i])
						c.color = self.colors[i]
				break

		self.prevnum = numcommunities
		self.prevnumisolates = numisolates
		
		
	def getTitle(self):
		return("gntool")

gntool()


