package com.oy.shared.scample.java;

import com.oy.shared.scample.actor.Actor;
import com.oy.shared.scample.actor.Message;
import com.oy.shared.scample.actor.MessageBus;

class PingMsg extends Message {
	final Ping sender;
	public PingMsg(Ping sender){
		this.sender = sender;
	}
}

class PongMsg extends Message {
	final Pong sender;
	public PongMsg(Pong sender){
		this.sender = sender;
	}
}

class StopMsg extends Message {
	
}	

class Ping extends Actor {
	private Pong pong;
	private int pingsLeft;
	
	public Ping(int count, Pong pong) {
		this.pong = pong;
		this.pingsLeft = count - 1;
	}
	
	public void start(){
		super.start();
		
		PingMsg pingMsg = new PingMsg(this);
		pong.postMessage(pingMsg);
	}
	
	public void react(Message msg) {
		if (msg instanceof PongMsg) {
			if (pingsLeft % 1000 == 0) {
				System.out.println("Ping: pong");
			}
			if (pingsLeft > 0) { 
				PingMsg pingMsg = new PingMsg(this);
				pong.postMessage(pingMsg);
				pingsLeft -= 1;
			} else {
				System.out.println("Ping: stop");
				pong.postMessage(new StopMsg());
				stop();
			}
		}
	}
}

class Pong extends Actor {
	private int pongCount;
	
	public void react(Message msg){
		if (msg instanceof PingMsg){
			PingMsg pingMsg = (PingMsg) msg;
			if (pongCount % 1000 == 0) { 
	            System.out.println("Pong: ping " + pongCount);
			}
			
			PongMsg pongMsg = new PongMsg(this);
			pingMsg.sender.postMessage(pongMsg);
	        pongCount = pongCount + 1;
	        
	        return;
		}
		
		if (msg instanceof StopMsg){
			System.out.println("Pong: stop");
			stop();
			
			return;
		}
	}
}

public class PingPongJava {
  
	public static void run(){
		MessageBus mbus = new MessageBus();
		mbus.start();
		
		Pong pong = new Pong();
		Ping ping = new Ping(100000, pong);
		ping.start();
		pong.start();
		    
		mbus.stopWhenActorsFinish();
	}
}
