import java.util.Scanner;

// Sensor Data Structures
class CameraData {
    enum ObjectType {
        none,
        vehicle,
        pedestrian,
        bicycle,
        stopLight,
        speedLimit
    }

    ObjectType object;
}

class LidarData {
    enum ObjectType {
        roadCurvature,
        smallObstruction,
        largeObstruction,
    }

    ObjectType object;
}

class GPSData {
    double curr_longitude;
    double curr_latitude;
    double dest_longitude;
    double dest_latitude;
}

// Perception Module - processes camera, lidar and GPS data
class PerceptionModule {
    private int timer = 0; // increments once per hour
    private final int MAX_TIME = 6;

    void processCameraData(CameraData cameraData) {
        switch (timer) {
            case 0:
                cameraData.object = CameraData.ObjectType.none;
                break;
            case 1:
                cameraData.object = CameraData.ObjectType.vehicle;
                break;
            case 2:
                cameraData.object = CameraData.ObjectType.pedestrian;
                break;
            case 3:
                cameraData.object = CameraData.ObjectType.bicycle;
                break;
            case 4:
                cameraData.object = CameraData.ObjectType.stopLight;
                break;
            case 5:
                cameraData.object = CameraData.ObjectType.speedLimit;
                break;
            default:
                cameraData.object = CameraData.ObjectType.none;
        }
    }

    void processLidarData(LidarData lidarData) {
        switch (timer) {
            case 0:
            case 3:
                lidarData.object = LidarData.ObjectType.roadCurvature;
                break;
            case 1:
            case 4:
                lidarData.object = LidarData.ObjectType.smallObstruction;
                break;
            case 2:
            case 5:
                lidarData.object = LidarData.ObjectType.largeObstruction;
                break;
            default:
                lidarData.object = LidarData.ObjectType.roadCurvature;
        }
    }

    void processGPSData(GPSData gpsData, double speed, double direction) {
        gpsData.curr_longitude += 180.0 * speed * Math.sin(Math.PI / 180.0 * direction) / 40040.00;
        gpsData.curr_latitude += 180.0 * speed * Math.cos(Math.PI / 180.0 * direction) / 40040.00;
    }

    void incrementTime() {
        ++timer;
        timer = timer % MAX_TIME;
    }
}

// Planning Module - plans a route based on GPS data and obstacle information (LIDAR data)
class PlanningModule {
    // write a function to plan your route based on current and destination gps data
    // write a function to update your route based on camera and lidar data
}

// Control Module - this module brings together gps data, sensor data, and planning data
class ControlModule {
    // write a function to initialize GPS data
    // write a function to adjust speed and direction based on:
    // - the processing of sensor data
    // - the planning of your route
    // - the updating of your route
    // end your journey after 24 hours or within 25km of your destination
}

// Autonomous Driving System - starts, runs and stops the simulation
class AutonomousDrivingSystem {
    // write a function to initialize data
    // write a function to run the overall simulation
}

public class AutoDrivingSystem {
    public static void main(String[] args) {
        // Create an autonomous driving system
        AutonomousDrivingSystem autonomousDrivingSystem = new AutonomousDrivingSystem();
        double latitude1, latitude2;
        double longitude1, longitude2;

        Scanner scanner = new Scanner(System.in);

        System.out.print("What is your initial location (latitude): ");
        latitude1 = scanner.nextDouble();
        System.out.print("                             (longitude): ");
        longitude1 = scanner.nextDouble();

        System.out.print("What is your destination location (latitude): ");
        latitude2 = scanner.nextDouble();
        System.out.print("                                 (longitude): ");
        longitude2 = scanner.nextDouble();

        scanner.close();

        autonomousDrivingSystem.initGpsData(latitude1, longitude1, latitude2, longitude2);

        // Process the sensor data
        autonomousDrivingSystem.runSimulation();

        System.out.println("You have arrived! (close enough)");
    }
}
