diff --git a/FerryTerminal/FerryTerminal.sln b/FerryTerminal/FerryTerminal.sln
new file mode 100644
index 0000000..19a48b2
--- /dev/null
+++ b/FerryTerminal/FerryTerminal.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.15
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FerryTerminal", "FerryTerminal\FerryTerminal.csproj", "{48FE9CAA-98AE-49EF-B7DF-60B27EAAD3FE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {48FE9CAA-98AE-49EF-B7DF-60B27EAAD3FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {48FE9CAA-98AE-49EF-B7DF-60B27EAAD3FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {48FE9CAA-98AE-49EF-B7DF-60B27EAAD3FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {48FE9CAA-98AE-49EF-B7DF-60B27EAAD3FE}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C22082BB-88AD-4C85-A182-8A5A4F61D3A0}
+ EndGlobalSection
+EndGlobal
diff --git a/FerryTerminal/FerryTerminal/App.config b/FerryTerminal/FerryTerminal/App.config
new file mode 100644
index 0000000..00bfd11
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FerryTerminal/FerryTerminal/CargoVehicle.cs b/FerryTerminal/FerryTerminal/CargoVehicle.cs
new file mode 100644
index 0000000..6103da1
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/CargoVehicle.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class CargoVehicle : GasVehicle, ICargoCarrier
+ {
+ public bool CargoDoorOpen { get; set; }
+
+ public CargoVehicle(VehicleType vehicleType) : base(vehicleType)
+ {
+ }
+
+ new public static CargoVehicle GetNewInstance(VehicleType vehicleType)
+ {
+ return new CargoVehicle(vehicleType);
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/ElectricVehicle.cs b/FerryTerminal/FerryTerminal/ElectricVehicle.cs
new file mode 100644
index 0000000..c9af740
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/ElectricVehicle.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class ElectricVehicle : Vehicle, IElectricUser
+ {
+ public int BatteryPercent { get; set; }
+
+ public ElectricVehicle(VehicleType vehicleType) : base(vehicleType)
+ {
+ BatteryPercent = RandomPercent();
+ }
+
+ public static ElectricVehicle GetNewInstance(VehicleType vehicleType)
+ {
+ return new ElectricVehicle(vehicleType);
+ }
+
+ public bool NeedsRecharge()
+ {
+ return BatteryPercent <= 10;
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/Ferry.cs b/FerryTerminal/FerryTerminal/Ferry.cs
new file mode 100644
index 0000000..23614a6
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/Ferry.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ enum FerryType
+ {
+ Small,
+ Large,
+ Eco
+ }
+
+ class Ferry
+ {
+ public FerryType FerryType { get; private set; }
+
+ int _capacity;
+
+ IList _acceptedVehicleTypeList;
+
+ List _vehicleList = new List();
+
+ public Ferry(FerryType ferryType, int capacity, IList acceptedVehicleTypeList)
+ {
+ FerryType = ferryType;
+
+ _capacity = capacity;
+
+ _acceptedVehicleTypeList = acceptedVehicleTypeList;
+ }
+
+ public bool AcceptVehicle(IVehicle vehicle)
+ {
+ if (_acceptedVehicleTypeList.Contains(vehicle.VehicleType))
+ {
+ _vehicleList.Add(vehicle);
+
+ if (_vehicleList.Count == _capacity)
+ {
+ // sail away and come back
+
+ _vehicleList.Clear();
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/FerryTerminal.cs b/FerryTerminal/FerryTerminal/FerryTerminal.cs
new file mode 100644
index 0000000..0855c22
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/FerryTerminal.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ enum FerryTerminalLocation
+ {
+ Slovenia,
+ Croatia
+ }
+
+ class FerryTerminal
+ {
+ float _income = 0;
+
+ FerryTerminalLocation _ferryTerminalLocation;
+
+ IDictionary _vehicleTicketPriceDictionary;
+
+ List _ferryList = new List();
+
+ Queue _terminalEmployeeList = new Queue();
+
+ public FerryTerminal(FerryTerminalLocation ferryTerminalLocation, IDictionary vehicleTicketPriceDictionary)
+ {
+ _ferryTerminalLocation = ferryTerminalLocation;
+
+ _vehicleTicketPriceDictionary = vehicleTicketPriceDictionary;
+
+ _terminalEmployeeList.Enqueue(new TerminalEmployee(0, 0.1f));
+ _terminalEmployeeList.Enqueue(new TerminalEmployee(1, 0.11f));
+
+ _ferryList.Add(new Ferry(FerryType.Small, 8, new List { VehicleType.Car, VehicleType.Van }));
+ _ferryList.Add(new Ferry(FerryType.Large, 6, new List { VehicleType.Bus, VehicleType.Truck }));
+ _ferryList.Add(new Ferry(FerryType.Eco, 10, new List { VehicleType.Electric, VehicleType.Hybrid }));
+ }
+
+ public void ProcessVehicle(IVehicle vehicle)
+ {
+ Console.WriteLine("Vehicle location: Arrival");
+
+ if (vehicle is ITicketPayer)
+ {
+ ChargeTicket(vehicle as ITicketPayer);
+ }
+
+ if (vehicle is IGasUser)
+ {
+ FillUpGas(vehicle as IGasUser);
+ }
+
+ if (vehicle is IElectricUser)
+ {
+ FillUpBattery(vehicle as IElectricUser);
+ }
+
+ if (vehicle is ICargoCarrier)
+ {
+ CustomsInspection(vehicle as ICargoCarrier);
+ }
+
+ LoadVehicleOnFerry(vehicle);
+
+ Console.WriteLine();
+ }
+
+ private void ChargeTicket(ITicketPayer ticketPayer)
+ {
+ Console.WriteLine("Charging ticket for " + ticketPayer.GetTicketType());
+
+ float price = _vehicleTicketPriceDictionary[ticketPayer.GetTicketType()];
+
+ float amount = ticketPayer.GetMoney(price);
+
+ TerminalEmployee terminalEmployee = _terminalEmployeeList.Dequeue();
+ float salary = amount * terminalEmployee.IncomePercent;
+ terminalEmployee.AddMoney(salary);
+ amount -= salary;
+ _terminalEmployeeList.Enqueue(terminalEmployee);
+
+ _income += amount;
+
+ Console.WriteLine("Terminal income is now " + _income);
+ }
+
+ private void FillUpGas(IGasUser gasUser)
+ {
+ Console.WriteLine("Amount of gas " + gasUser.GasPercent);
+
+ if (gasUser.NeedsRefill())
+ {
+ gasUser.GasPercent = 100;
+
+ Console.WriteLine("Vehicle location: Gas station");
+ }
+ }
+
+ private void FillUpBattery(IElectricUser electricUser)
+ {
+ Console.WriteLine("Amount of battery " + electricUser.BatteryPercent);
+
+ if (electricUser.NeedsRecharge())
+ {
+ electricUser.BatteryPercent = 100;
+
+ Console.WriteLine("Vehicle location: Battery recharge station");
+ }
+ }
+
+ private void CustomsInspection(ICargoCarrier cargoCarrier)
+ {
+ Console.WriteLine("Vehicle location: Customs inspection");
+
+ Console.WriteLine("Cargo doors are open: " + cargoCarrier.CargoDoorOpen);
+
+ cargoCarrier.CargoDoorOpen = true;
+
+ Console.WriteLine("Cargo doors are open: " + cargoCarrier.CargoDoorOpen);
+
+ cargoCarrier.CargoDoorOpen = false;
+
+ Console.WriteLine("Cargo doors are open: " + cargoCarrier.CargoDoorOpen);
+ }
+
+ private void LoadVehicleOnFerry(IVehicle vehicle)
+ {
+ foreach (Ferry ferry in _ferryList)
+ {
+ if (ferry.AcceptVehicle(vehicle))
+ {
+ Console.WriteLine("Vehicle location: " + ferry.FerryType + " ferry");
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/FerryTerminal.csproj b/FerryTerminal/FerryTerminal/FerryTerminal.csproj
new file mode 100644
index 0000000..3aa9465
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/FerryTerminal.csproj
@@ -0,0 +1,66 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {48FE9CAA-98AE-49EF-B7DF-60B27EAAD3FE}
+ Exe
+ FerryTerminal
+ FerryTerminal
+ v4.6.1
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FerryTerminal/FerryTerminal/GasVehicle.cs b/FerryTerminal/FerryTerminal/GasVehicle.cs
new file mode 100644
index 0000000..ccc4a55
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/GasVehicle.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class GasVehicle : Vehicle, IGasUser
+ {
+ public int GasPercent { get; set; }
+
+ public GasVehicle(VehicleType vehicleType) : base(vehicleType)
+ {
+ GasPercent = RandomPercent();
+ }
+
+ public static GasVehicle GetNewInstance(VehicleType vehicleType)
+ {
+ return new GasVehicle(vehicleType);
+ }
+
+ public bool NeedsRefill()
+ {
+ return GasPercent <= 10;
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/HybridVehicle.cs b/FerryTerminal/FerryTerminal/HybridVehicle.cs
new file mode 100644
index 0000000..b275bb6
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/HybridVehicle.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class HybridVehicle : Vehicle, IElectricUser, IGasUser
+ {
+ public int BatteryPercent { get; set; }
+
+ public int GasPercent { get; set; }
+
+ public HybridVehicle(VehicleType vehicleType) : base(vehicleType)
+ {
+ BatteryPercent = RandomPercent();
+
+ GasPercent = RandomPercent();
+ }
+
+ public static HybridVehicle GetNewInstance(VehicleType vehicleType)
+ {
+ return new HybridVehicle(vehicleType);
+ }
+
+ public bool NeedsRecharge()
+ {
+ return BatteryPercent <= 10 && GasPercent <= 50;
+ }
+
+ public bool NeedsRefill()
+ {
+ return GasPercent <= 10 && BatteryPercent <= 50;
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/ICargoCarrier.cs b/FerryTerminal/FerryTerminal/ICargoCarrier.cs
new file mode 100644
index 0000000..dadda0c
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/ICargoCarrier.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ interface ICargoCarrier
+ {
+ bool CargoDoorOpen { get; set; }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/IElectricUser.cs b/FerryTerminal/FerryTerminal/IElectricUser.cs
new file mode 100644
index 0000000..79cd52c
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/IElectricUser.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ interface IElectricUser
+ {
+ int BatteryPercent { get; set; }
+
+ bool NeedsRecharge();
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/IGasUser.cs b/FerryTerminal/FerryTerminal/IGasUser.cs
new file mode 100644
index 0000000..30a1234
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/IGasUser.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ interface IGasUser
+ {
+ int GasPercent { get; set; }
+
+ bool NeedsRefill();
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/ITicketPayer.cs b/FerryTerminal/FerryTerminal/ITicketPayer.cs
new file mode 100644
index 0000000..ac9dceb
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/ITicketPayer.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ interface ITicketPayer
+ {
+ VehicleType GetTicketType();
+
+ float GetMoney(float amount);
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/IVehicle.cs b/FerryTerminal/FerryTerminal/IVehicle.cs
new file mode 100644
index 0000000..4debf35
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/IVehicle.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ enum VehicleType
+ {
+ Bus,
+ Car,
+ Truck,
+ Van,
+ Electric,
+ Hybrid,
+
+ Count
+ }
+
+ interface IVehicle
+ {
+ VehicleType VehicleType { get; }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/Program.cs b/FerryTerminal/FerryTerminal/Program.cs
new file mode 100644
index 0000000..1a1d52d
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/Program.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ VehicleFactory.Register(VehicleType.Bus, GasVehicle.GetNewInstance);
+ VehicleFactory.Register(VehicleType.Car, GasVehicle.GetNewInstance);
+ VehicleFactory.Register(VehicleType.Truck, CargoVehicle.GetNewInstance);
+ VehicleFactory.Register(VehicleType.Van, CargoVehicle.GetNewInstance);
+ VehicleFactory.Register(VehicleType.Electric, ElectricVehicle.GetNewInstance);
+ VehicleFactory.Register(VehicleType.Hybrid, HybridVehicle.GetNewInstance);
+
+ List ferryTerminalList = new List
+ {
+ new FerryTerminal(FerryTerminalLocation.Croatia, new Dictionary
+ {
+ { VehicleType.Electric, 1 },
+ { VehicleType.Hybrid, 2 },
+ { VehicleType.Car, 3 },
+ { VehicleType.Van, 4 },
+ { VehicleType.Bus, 5 },
+ { VehicleType.Truck, 6 }
+ })
+ };
+
+ while (Console.ReadKey(true).Key != ConsoleKey.Escape)
+ {
+ foreach (FerryTerminal ferryTerminal in ferryTerminalList)
+ {
+ ferryTerminal.ProcessVehicle(VehicleFactory.RandomVehicle());
+ }
+ }
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/Properties/AssemblyInfo.cs b/FerryTerminal/FerryTerminal/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6337808
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FerryTerminal")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FerryTerminal")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("48fe9caa-98ae-49ef-b7df-60b27eaad3fe")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/FerryTerminal/FerryTerminal/TerminalEmployee.cs b/FerryTerminal/FerryTerminal/TerminalEmployee.cs
new file mode 100644
index 0000000..d682ebd
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/TerminalEmployee.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class TerminalEmployee
+ {
+ int _id;
+
+ float _money;
+
+ public float IncomePercent { get; private set; }
+
+ public TerminalEmployee(int id, float incomePercent)
+ {
+ _id = id;
+
+ IncomePercent = incomePercent;
+ }
+
+ public void AddMoney(float amount)
+ {
+ _money += amount;
+
+ Console.WriteLine("Employee " + _id + " received " + amount + ", total is " + _money);
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/Vehicle.cs b/FerryTerminal/FerryTerminal/Vehicle.cs
new file mode 100644
index 0000000..e521eb8
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/Vehicle.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class Vehicle : IVehicle, ITicketPayer
+ {
+ static Random _random = new Random();
+
+ public VehicleType VehicleType { get; private set; }
+
+ float _money = 100;
+
+ public Vehicle(VehicleType vehicleType)
+ {
+ VehicleType = vehicleType;
+ }
+
+ public static int RandomPercent()
+ {
+ return _random.Next(101);
+ }
+
+ public VehicleType GetTicketType()
+ {
+ return VehicleType;
+ }
+
+ public float GetMoney(float amount)
+ {
+ if (_money >= amount)
+ {
+ _money -= amount;
+
+ Console.WriteLine("Vehicle payed " + amount);
+
+ return amount;
+ }
+
+ throw new Exception("Not enough money");
+ }
+ }
+}
diff --git a/FerryTerminal/FerryTerminal/VehicleFactory.cs b/FerryTerminal/FerryTerminal/VehicleFactory.cs
new file mode 100644
index 0000000..953e6bb
--- /dev/null
+++ b/FerryTerminal/FerryTerminal/VehicleFactory.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FerryTerminal
+{
+ class VehicleFactory
+ {
+ static Random _random = new Random();
+
+ static Dictionary> _vehicleFactoryMethodList = new Dictionary>();
+
+ public static void Register(VehicleType vehicleType, Func newInstanceFunc)
+ {
+ _vehicleFactoryMethodList.Add(vehicleType, newInstanceFunc);
+ }
+
+ public static IVehicle RandomVehicle()
+ {
+ VehicleType vehicleType = (VehicleType)_random.Next((int)VehicleType.Count);
+
+ return _vehicleFactoryMethodList[vehicleType](vehicleType);
+ }
+ }
+}