/** HelloWorld_EventNotification
 *
 *       The HyperCast HelloWorld programs demonstrate various aspects of
 *       the HyperCast API.  The programs create an overlay socket that
 *       sends and receives messages.
 *
 *       The HelloWorld_Notification program uses the event 
 *       notification mechanism of overlay sockets. 
 *       This program uses, among others, the event NODE_HASBECOMESTABLE. Since this 
 *       event is only defined for the DT protocol, this program should be run with the 
 *       DT overlay protocol (e.g., DTBuddyList)  
 *       
 *       This file corresponds to an example program in the HyperCast API description
 *       (see Chapter:  "API - Advanced", Section: "3"). 
 *
 * @author HyperCast Team, University of Toronto
 * @version 2006
 *
 */


import java.util.*;
import java.io.*;
import java.net.*;
import hypercast.*;
import hypercast.events.*;

public class HelloWorld_EventNotification implements I_ReceiveCallback
{ 
	
	//   The string we send 
	String MyString = new String("Hello World");
	
	//   The overlay socket 
	I_OverlaySocket MySocket = null;
	
	//   The configuration object
	HyperCastConfig ConfObj = null;
	
	public static void main(String[] args)
	{
		// Create a new HelloWorld_CallBack instance
		HelloWorld_EventNotification hw = new HelloWorld_EventNotification();
	}
	
	public void ReceiveCallback(I_OverlayMessage msg)
	{
		// Extract the payload and the logical address of the source
		byte[] data = msg.getPayload();
		String Src = msg.getSourceAddress().toString();
		
		
		// Print the payload (Skip messages sent by this program) 
		if(!msg.getSourceAddress().equals(MySocket.getLogicalAddress()))
			System.out.println("Received <"+ new String(data) + "> from logical address: " + Src + ".");
	}
	
	
	public HelloWorld_EventNotification ()
	{
		//  Create a configuration object
		ConfObj = HyperCastConfig.createConfig("hypercast.xml");
		
		// Create a notification handler 
		
		
		// NotificationHandler provides the default event handling method: 
		//  (1) Applictions can block on events with the waitUntil.. methods
		//NotificationHandler cnh = new NotificationHandler();
		
		
		// MyNotification extends NotificationHandler by overwriting 
		// some event handling methods. 
		//  (1) Applictions can block on events with the waitUntil... methods as before
		//  (2) Overwritten event handling methods are run when event is raised  
		MyNotification_handler cnh = new MyNotification_handler();
		
		// Create an overlay socket with the notification handler (second parameter)
		MySocket=ConfObj.createOverlaySocket(this, cnh);
		
		// Join the overlay network 
		MySocket.joinOverlay();
		
		// Note: NODE_ISSTABLE is only available with DT protocol
		cnh.waitUntil_NODE_ISSTABLE();
		
		
		// Print the logical address */ 
		String MyLogicalAddress = MySocket.getLogicalAddress().toString();
		System.out.println("Logical address is " + MyLogicalAddress + ".");
		
		// Wait until Neigbhorhood has changed, but not more than 5 seconds 
		//System.out.println("Wait max. 5 seconds for change of neighborhood.");
		cnh.waitUntil_NODE_NEIGHBORHOODCHANGED(5000);
		System.out.println("Now wait 5 sec's for neighborchange.");
		long start = System.currentTimeMillis();
		cnh.waitUntil_NODE_NEIGHBORHOODCHANGED(5000);
		long waittime = System.currentTimeMillis() - start;
		System.out.println("Continue. Waiting time was: " + waittime); 
		
		// Send messages 
		for(int i=1;i<10;i++) {
			
			// wait 5 seconds   
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {} 
			
			// Convert the string to a byte array and create a message 
			byte[] MyData = MyString.getBytes(); 
			I_OverlayMessage MyMessage = MySocket.createMessage(MyData);
			
			/* The message is sent to all members of the overlay */
			MySocket.sendToAll(MyMessage);
			System.out.println(" message sent to other members ...");
			
		}
		// Close socket 
		MySocket.closeSocket();
	}
}	

/*
 * MyNotificaton_handler overwrites some of the (by default empty) event handling methods 
 * of NotificationHandler.
 */
class MyNotification_handler extends NotificationHandler 
{
	
	public void handle_NODE_ISSTABLE (final NODE_ISSTABLE event) {
		System.out.println("MyNotificaton_handler: NODE_ISSTABLE occured at:"+ event.getTimestamp());
	}
	
	public void handle_NODE_LEAVEOVERLAY (final NODE_LEAVEOVERLAY event) {
		System.out.println("MyNotificaton_handler: NODE_LEAVEGROUP occured at:"+ event.getTimestamp());
	}
	
	public void handle_NODE_NEIGHBORHOODCHANGED (final NODE_LOGICALADDRESSCHANGED event) {
		System.out.println("MyNotificaton_handler: NODE_LEAVEGROUP occured at:"+ event.getTimestamp());
	}
}