package seng302.Networking.MessageDecoders;

import seng302.Networking.Messages.BoatStatus;

import java.util.ArrayList;
import java.util.Arrays;

import static seng302.Networking.Utils.ByteConverter.*;

/**
 * Created by hba56 on 21/04/17.
 */
public class RaceStatusDecoder {
    private byte versionNum;
    private byte[] timeBytes;
    private byte[] raceID;
    private byte raceStatus;
    private byte[] expectedStart;
    private byte[] raceWind;
    private byte[] windSpeed;
    private byte numBoats;
    private byte bytesRaceType;
    private byte[] boatsBytes;

    private long time;
    private int race;
    private int raceState;
    private long startTime;
    private int raceWindDir;
    private short raceWindSpeed;
    private int numberOfBoats;
    private int raceType;
    private ArrayList<BoatStatus> boats = new ArrayList<>();


    public RaceStatusDecoder(byte[] encodedRaceStatus){
        versionNum = encodedRaceStatus[0];
        timeBytes = Arrays.copyOfRange(encodedRaceStatus, 1, 7);
        raceID = Arrays.copyOfRange(encodedRaceStatus, 7, 11);
        raceStatus = encodedRaceStatus[11];
        expectedStart = Arrays.copyOfRange(encodedRaceStatus, 12, 18);
        raceWind = Arrays.copyOfRange(encodedRaceStatus, 18, 20);
        windSpeed = Arrays.copyOfRange(encodedRaceStatus, 20, 22);
        numBoats = encodedRaceStatus[22];
        bytesRaceType = encodedRaceStatus[23];
        boatsBytes = Arrays.copyOfRange(encodedRaceStatus, 24, 25+20*this.numBoats);

        time = bytesToLong(timeBytes);
        race = bytesToInt(raceID);
        raceState = bytesToInt(raceStatus);
        startTime = bytesToLong(expectedStart);
        raceWindDir = bytesToInt(raceWind);
        raceWindSpeed = bytesToShort(windSpeed);
        numberOfBoats = bytesToInt(numBoats);

        int boatLoopIndex = 0;

        for (int i=0; i < numberOfBoats; i++) {
            byte[] boatBytes = Arrays.copyOfRange(boatsBytes, boatLoopIndex, boatLoopIndex+20);

            byte[] sourceID = Arrays.copyOfRange(boatBytes, 0, 3);
            byte boatStatus = boatBytes[4];
            byte legNumber = boatBytes[5];
            byte numPenaltiesAwarded = boatBytes[6];
            byte numPenaltiesServed = boatBytes[7];
            byte[] estTimeAtNextMark = Arrays.copyOfRange(boatBytes, 8, 14);
            byte[] estTimeAtFinish = Arrays.copyOfRange(boatBytes, 14, 20);

            BoatStatus boat = new BoatStatus(bytesToInt(sourceID),boatStatus,
                    legNumber, numPenaltiesAwarded, numPenaltiesServed,
                    bytesToLong(estTimeAtNextMark), bytesToLong(estTimeAtFinish));

            boats.add(boat);
            boatLoopIndex += 20;
        }
    }

    public byte getVersionNum() {
        return versionNum;
    }

    public long getTime() {
        return time;
    }

    public int getRace() {
        return race;
    }

    public int getRaceState() {
        return raceState;
    }

    public long getStartTime() {
        return startTime;
    }

    public int getRaceWindDir() {
        return raceWindDir;
    }

    public short getRaceWindSpeed() {
        return raceWindSpeed;
    }

    public int getNumberOfBoats() {
        return numberOfBoats;
    }

    public int getRaceType() {
        return raceType;
    }

    public ArrayList<BoatStatus> getBoats() {
        return boats;
    }
}
