# Author: Mete Rodoper

# For more detail refer the How to code and use Various Mobility Model Scripts to Emulate Mobility at ORBIT tutorial

#!/usr/bin/perl

use Math::Round qw(:all);
use Math::Trig 'deg2rad';

#############################################################################################################
######################################## Enter the values here ##############################################
#############################################################################################################

$sourceXValue = 19; # Source X value
$sourceYValue = 15; # Source Y value

$walkDuration = 1000; # Walk duration in unit time in one direction. When this time elapses change direcion
$speed = 100; # Average speed of the VMs 
$angle = 360; # Angle randomness of the movements
$numberOfStops = 2; # Maximum distance that a node can jump at an iteration

#############################################################################################################
#############################################################################################################
#############################################################################################################

$mobileNumber = 0;	

$numberOfStopsMax = $numberOfStops;
$mobileNumberIterator = $mobileNumber;
$intervalTime = 0;

$previousNode = "";

$pointX = $sourceXValue;
$pointY = $sourceYValue;

while ($numberOfStops > 0)
{
	$speedChosen = int(rand($speed));
	$angleChosen = int(rand($angle));
	
	#print "$angleChosen\n";

	$noOfHops = $walkDuration/$speed;

	while ($noOfHops > 0)
	{
		$pointX = $pointX + cos($angleChosen);
		$pointY = $pointY + sin($angleChosen);

		$fractionX = abs($pointX - int($pointX));
		$fractionY = abs($pointY - int($pointY));
		
		$firstQuarter = $fractionY * $fractionY + $fractionX * $fractionX;
		$secondQuarter = $fractionY * $fractionY + (1-$fractionX) * (1-$fractionX);
		$thirdQuarter = (1-$fractionY) * (1-$fractionY) + (1-$fractionX) * (1-$fractionX);
		$fourthQuarter = (1-$fractionY) * (1-$fractionY) + $fractionX * $fractionX;

		$floorX = int($pointX);
		$floorY = int($pointY);
	
		if($pointX < 0)
		{
			$ceilingX = $floorX - 1;	
		}
		else
		{	
			$ceilingX = $floorX + 1;
		}

		if($pointY < 0)
		{
			$ceilingY = $floorY - 1;	
		}
		else
		{	
			$ceilingY = $floorY + 1;
		}

		$minDistance = $firstQuarter;
		$min = "1";
		if ($secondQuarter < $minDistance)
		{
			$min = "2";
			$minDistance = $secondQuarter;
		}
		if ($thirdQuarter < $minDistance)
		{
			$min = "3";
			$minDistance = $thirdQuarter;
		}
		if ($fourthQuarter < $minDistance)
		{
			$min = "4";
		}

		if ($min == "1")
		{
			if((int(abs($floorX - 1)/20)%2) == 1)
			{
				$newX = 20-abs(($floorX - 1)-(int(($floorX - 1)/20)*20));
			}
			else
			{
				$newX = abs(($floorX - 1)-int(($floorX - 1)/20)*20);
			}

			if ((int(abs($floorY - 1)/20)%2) == 1)
			{
				$newY = 20-abs(($floorY - 1)-(int(($floorY - 1)/20)*20));
			}
			else
			{
				$newY = abs(($floorY - 1)-int(($floorY - 1)/20)*20);
			}		

			$nodeNameAndTime = "node$newX-$newY";
			if ($previousNode ne $nodeNameAndTime)
			{
				$toFile = "$intervalTime $nodeNameAndTime";
				print "$toFile\n";;
				push @{$store{$mobileNumber}}, $toFile;
				$previousNode = $nodeNameAndTime;
				$runningTime--;
				$intervalTime = $intervalTime + $speed;
			}
		}
		elsif ($min == "2")
		{
			if ((int(abs($ceilingX - 1)/20)%2) == 1)
			{
				$newX = 20-abs(($ceilingX - 1)-(int(($ceilingX - 1)/20)*20));
			}
			else
			{
				$newX = abs(($ceilingX - 1)-int(($ceilingX - 1)/20)*20);
			}

			if((int(abs($floorY - 1)/20)%2) == 1)
			{
				$newY = 20-abs(($floorY - 1)-(int(($floorY - 1)/20)*20));
			}
			else
			{
				$newY = abs(($floorY - 1)-int(($floorY - 1)/20)*20);
			}
			$nodeNameAndTime = "node$newX-$newY";
			if ($previousNode ne $nodeNameAndTime)
			{
				$toFile = "$intervalTime $nodeNameAndTime";
				print "$toFile\n";;
				push @{$store{$mobileNumber}}, $toFile;
				$previousNode = $nodeNameAndTime;
				$runningTime--;
				$intervalTime = $intervalTime + $speed;
			}
		}
		elsif ($min == "3")
		{
			if((int(abs($ceilingX - 1)/20)%2) == 1)
			{
				$newX = 20-abs(($ceilingX - 1)-(int(($ceilingX - 1)/20)*20));
			}
			else
			{
				$newX = abs(($ceilingX - 1)-int(($ceilingX - 1)/20)*20);
			}

			if((int(abs($ceilingY - 1)/20)%2) == 1)
			{
				$newY = 20-abs(($ceilingY - 1)-(int(($ceilingY - 1)/20)*20));
			}
			else
			{
				$newY = abs(($ceilingY - 1)-int(($ceilingY - 1)/20)*20);
			}

			$nodeNameAndTime = "node$newX-$newY";
			if ($previousNode ne $nodeNameAndTime)
			{
				$toFile = "$intervalTime $nodeNameAndTime";
				print "$toFile\n";;
				push @{$store{$mobileNumber}}, $toFile;
				$previousNode = $nodeNameAndTime;
				$runningTime--;
				$intervalTime = $intervalTime + $speed;
			}
		}
		elsif ($min == "4")
		{
			if((int(abs($floorX - 1)/20)%2) == 1)
			{
				$newX = 20-abs(($floorX - 1)-(int(($floorX - 1)/20)*20));
			}
			else
			{
				$newX = abs(($floorX - 1)-int(($floorX - 1)/20)*20);
			}

			if((int(abs($ceilingY - 1)/20)%2) == 1)
			{
				$newY = 20-abs(($ceilingY - 1)-(int(($ceilingY - 1)/20)*20));
			}
			else
			{
				$newY = abs(($ceilingY - 1)-int(($ceilingY - 1)/20)*20);
			}

			$nodeNameAndTime = "node$newX-$newY";
			if ($previousNode ne $nodeNameAndTime)
			{
				$toFile = "$intervalTime $nodeNameAndTime";
				print "$toFile\n";;
				push @{$store{$mobileNumber}}, $toFile;
				$previousNode = $nodeNameAndTime;
				$runningTime--;
				$intervalTime = $intervalTime + $speed;
			}
		}

		$noOfHops--;
	}

	
	$numberOfStopsToPrint = $numberOfStopsMax + 1 - $numberOfStops;
	$mobileNumberIteratorToPrint = $mobileNumberIterator +1;
	print "Destination No : $numberOfStopsToPrint is Reached for Mobile Node Number : $mobileNumberIteratorToPrint\n";	


	$pointX = $newX;
	$pointY = $newY;

	$numberOfStops--;
}

$mobileNumberIterator = 0;
$nodeNumber = $mobileNumberIterator + 1;

while (${$store{$mobileNumberIterator}}[$j] ne ())
{
	$tempWrite = ${$store{$mobileNumberIterator}}[$j];
	#print "$tempWrite\n";
	system("echo $tempWrite >> VM$nodeNumber.txt");
	$j = $j + 1;
}

