#include "ITS_ContainerCodec.hh"
#include "asn1/ItsPduHeader.h"
#include "asn1/ReferencePosition.h"
#include "asn1/PathHistory.h"
#include "asn1/ProtectedCommunicationZonesRSU.h"
#include "asn1/Heading.h"
#include "asn1/Speed.h"
#include "asn1/VehicleLength.h"
#include "asn1/LongitudinalAcceleration.h"
#include "asn1/Curvature.h"
#include "asn1/YawRate.h"
#include "asn1/SteeringWheelAngle.h"
#include "asn1/LateralAcceleration.h"
#include "asn1/VerticalAcceleration.h"
#include "asn1/CenDsrcTollingZone.h"
#include "asn1/CauseCode.h"
#include "asn1/PtActivation.h"
#include "asn1/ClosedLanes.h"

#define T2A(F)     titan2asn1c(t.F(), a.F)
#define T2A_O(F)   titan2asn1c_opt(t.F(), a.F)
#define A2T(F)     asn1c2titan(a.F)
#define A2T_O(T,F) asn1c2titan_opt<T>(a.F)

void titan2asn1c(const ITS__Container::ItsPduHeader& t, ItsPduHeader& a)
{
	T2A(protocolVersion);
	T2A(messageID);
	T2A(stationID);
}
ITS__Container::ItsPduHeader asn1c2titan(const ItsPduHeader& a)
{
	return ITS__Container::ItsPduHeader(
		asn1c2titan(a.protocolVersion),
		asn1c2titan(a.messageID),
		asn1c2titan(a.stationID)
		);
}

// ReferencePosition
void titan2asn1c(const ITS__Container::ReferencePosition& t, ReferencePosition& a)
{
	titan2asn1c(t.latitude(), a.latitude);
	titan2asn1c(t.longitude(), a.longitude);
	titan2asn1c(t.positionConfidenceEllipse(), a.positionConfidenceEllipse);
	titan2asn1c(t.altitude(), a.altitude);
}
ITS__Container::ReferencePosition asn1c2titan(const ReferencePosition& a)
{
	return ITS__Container::ReferencePosition(
		asn1c2titan(a.latitude),
		asn1c2titan(a.longitude),
		asn1c2titan(a.positionConfidenceEllipse),
		asn1c2titan(a.altitude)
		);
}

// VehicleRole
void titan2asn1c(const ITS__Container::VehicleRole& t, long& a)
{
	a = t.as_int();
}

// DeltaReferencePosition
void titan2asn1c(const ITS__Container::DeltaReferencePosition& t, DeltaReferencePosition& a)
{
	
	titan2asn1c(t.deltaLatitude(), a.deltaLatitude);
	titan2asn1c(t.deltaLongitude(), a.deltaLongitude);
	titan2asn1c(t.deltaAltitude(), a.deltaAltitude);
}
ITS__Container::DeltaReferencePosition asn1c2titan(const DeltaReferencePosition& a)
{
	return ITS__Container::DeltaReferencePosition(
		asn1c2titan(a.deltaLatitude),
		asn1c2titan(a.deltaLongitude),
		asn1c2titan(a.deltaAltitude)
		);
}

//PathPoint
void titan2asn1c(const ITS__Container::PathPoint& t, PathPoint& a)
{
	titan2asn1c(t.pathPosition(), a.pathPosition);
	titan2asn1c_opt(t.pathDeltaTime(), a.pathDeltaTime);
}
const ITS__Container::PathPoint asn1c2titan(const PathPoint& a)
{
	return ITS__Container::PathPoint(
		asn1c2titan(a.pathPosition),
		asn1c2titan_opt<INTEGER>(a.pathDeltaTime)
		);
}

//PathHistory
void titan2asn1c(const ITS__Container::PathHistory& t, PathHistory& a)
{
	titan2asn1c_seq<PathPoint>(t, a);
}

ITS__Container::PathHistory	asn1c2titan(const PathHistory& a)
{
	return asn1c2titan_seq<ITS__Container::PathHistory>(a);
}

// ProtectedCommunicationZone
void titan2asn1c(const ITS__Container::ProtectedZoneType& t, ProtectedZoneType_t& a)
{
	a = t.as_int();
}

// ProtectedCommunicationZone
void titan2asn1c(const ITS__Container::ProtectedCommunicationZone& t, ProtectedCommunicationZone_t& a)
{
	T2A(protectedZoneType);
	T2A_O(expiryTime);
	T2A(protectedZoneLatitude);
	T2A(protectedZoneLongitude);
	T2A_O(protectedZoneRadius);
	T2A_O(protectedZoneID);
}
ITS__Container::ProtectedCommunicationZone asn1c2titan(const ProtectedCommunicationZone_t& a)
{
	return ITS__Container::ProtectedCommunicationZone(
		asn1c2titan<ITS__Container::ProtectedZoneType>(a.protectedZoneType),
		A2T_O(INTEGER, expiryTime),
		A2T(protectedZoneLatitude),
		A2T(protectedZoneLongitude),
		A2T_O(INTEGER, protectedZoneRadius),
		A2T_O(INTEGER, protectedZoneID)
	);
}

// ProtectedCommunicationZonesRSU
void titan2asn1c(const ITS__Container::ProtectedCommunicationZonesRSU& t, ProtectedCommunicationZonesRSU& a)
{
	titan2asn1c_seq<ProtectedCommunicationZone>(t, a);
}

ITS__Container::ProtectedCommunicationZonesRSU asn1c2titan(const ProtectedCommunicationZonesRSU& a)
{
	return asn1c2titan_seq<ITS__Container::ProtectedCommunicationZonesRSU>(a);
}

// Heading
void titan2asn1c(const ITS__Container::Heading& t, Heading& a)
{
	titan2asn1c(t.headingValue(), a.headingValue);
	titan2asn1c(t.headingConfidence(), a.headingConfidence);
}
ITS__Container::Heading asn1c2titan(const Heading& a)
{
	return ITS__Container::Heading(
		asn1c2titan(a.headingValue),
		asn1c2titan(a.headingConfidence)
		);
}

// Speed
void titan2asn1c(const ITS__Container::Speed& t, Speed& a)
{
	titan2asn1c(t.speedValue(), a.speedValue);
	titan2asn1c(t.speedConfidence(), a.speedConfidence);
}
ITS__Container::Speed asn1c2titan(const Speed& a)
{
	return ITS__Container::Speed(
		asn1c2titan(a.speedValue),
		asn1c2titan(a.speedConfidence)
		);
}

void titan2asn1c(const ITS__Container::VehicleLengthConfidenceIndication& t, VehicleLengthConfidenceIndication_t& a)
{
	a = t.as_int();
}

// VehicleLength
void titan2asn1c(const ITS__Container::VehicleLength& t, VehicleLength& a)
{
	titan2asn1c(t.vehicleLengthValue(), a.vehicleLengthValue);
	titan2asn1c(t.vehicleLengthConfidenceIndication(), a.vehicleLengthConfidenceIndication);
}
ITS__Container::VehicleLength	  asn1c2titan(const VehicleLength& a)
{
	return ITS__Container::VehicleLength(
		asn1c2titan(a.vehicleLengthValue),
		asn1c2titan<ITS__Container::VehicleLengthConfidenceIndication>(a.vehicleLengthConfidenceIndication)
		);
}

// LongitudinalAcceleration
void titan2asn1c(const ITS__Container::LongitudinalAcceleration& t, LongitudinalAcceleration& a)
{
	titan2asn1c(t.longitudinalAccelerationValue(), a.longitudinalAccelerationValue);
	titan2asn1c(t.longitudinalAccelerationConfidence(), a.longitudinalAccelerationConfidence);
}
ITS__Container::LongitudinalAcceleration	  asn1c2titan(const LongitudinalAcceleration& a)
{
	return ITS__Container::LongitudinalAcceleration(
		asn1c2titan(a.longitudinalAccelerationValue),
		asn1c2titan(a.longitudinalAccelerationConfidence)
		);
}

// CurvatureConfidence
void titan2asn1c(const ITS__Container::CurvatureConfidence& t, CurvatureConfidence_t& a)
{
	a = t.as_int();
}

// Curvature
void titan2asn1c(const ITS__Container::Curvature& t, Curvature& a)
{
	titan2asn1c(t.curvatureValue(), a.curvatureValue);
	titan2asn1c(t.curvatureConfidence(), a.curvatureConfidence);
}
ITS__Container::Curvature asn1c2titan(const Curvature& a)
{
	return ITS__Container::Curvature(
		asn1c2titan(a.curvatureValue),
		asn1c2titan<ITS__Container::CurvatureConfidence>(a.curvatureConfidence)
		);
}

// YawRateConfidence
void titan2asn1c(const ITS__Container::YawRateConfidence& t, YawRateConfidence_t& a)
{
	a = t.as_int();
}

// YawRate
void titan2asn1c(const ITS__Container::YawRate&t, YawRate& a)
{
	titan2asn1c(t.yawRateValue(), a.yawRateValue);
	titan2asn1c(t.yawRateConfidence(), a.yawRateConfidence);
}

ITS__Container::YawRate	asn1c2titan(const YawRate& a)
{
	return ITS__Container::YawRate(
		asn1c2titan(a.yawRateValue),
		asn1c2titan<ITS__Container::YawRateConfidence>(a.yawRateConfidence)
		);
}

// SteeringWheelAngle
void                               titan2asn1c(const ITS__Container::SteeringWheelAngle&t, SteeringWheelAngle& a)
{
	titan2asn1c(t.steeringWheelAngleValue(), a.steeringWheelAngleValue);
	titan2asn1c(t.steeringWheelAngleConfidence(), a.steeringWheelAngleConfidence);
}

ITS__Container::SteeringWheelAngle asn1c2titan(const SteeringWheelAngle& a)
{
	return ITS__Container::SteeringWheelAngle(
		asn1c2titan(a.steeringWheelAngleValue),
		asn1c2titan(a.steeringWheelAngleConfidence)
		);
}

// LateralAcceleration
void titan2asn1c(const ITS__Container::LateralAcceleration&t, LateralAcceleration& a)
{
	titan2asn1c(t.lateralAccelerationValue(), a.lateralAccelerationValue);
	titan2asn1c(t.lateralAccelerationConfidence(), a.lateralAccelerationConfidence);
}

ITS__Container::LateralAcceleration	 asn1c2titan(const LateralAcceleration& a)
{
	return ITS__Container::LateralAcceleration(
		asn1c2titan(a.lateralAccelerationValue),
		asn1c2titan(a.lateralAccelerationConfidence)
		);
}

// VerticalAcceleration
void titan2asn1c(const ITS__Container::VerticalAcceleration&t, VerticalAcceleration& a)
{
	T2A(verticalAccelerationValue);
	T2A(verticalAccelerationConfidence);
}
ITS__Container::VerticalAcceleration asn1c2titan(const VerticalAcceleration& a)
{
	return ITS__Container::VerticalAcceleration(
		A2T(verticalAccelerationValue),
		A2T(verticalAccelerationConfidence)
		);
}

// CenDsrcTollingZone
void                              titan2asn1c(const ITS__Container::CenDsrcTollingZone&t, CenDsrcTollingZone& a)
{
	T2A(protectedZoneLatitude);
	T2A(protectedZoneLongitude);
	T2A_O(cenDsrcTollingZoneID);
}
ITS__Container::CenDsrcTollingZone asn1c2titan(const CenDsrcTollingZone& a)
{
	return ITS__Container::CenDsrcTollingZone(
		A2T(protectedZoneLatitude),
		A2T(protectedZoneLongitude),
		A2T_O(INTEGER, cenDsrcTollingZoneID)
		);
}

// DriveDirection
void titan2asn1c(const ITS__Container::DriveDirection&t, long& a)
{
	a = t.as_int();
}

// CurvatureCalculationMode
void titan2asn1c(const ITS__Container::CurvatureCalculationMode&t, long& a)
{
	a = t.as_int();
}

// DangerousGoodsBasic
void                              titan2asn1c(const ITS__Container::DangerousGoodsBasic&t, long& a)
{
	a = t.as_int();
}

// CauseCode
void titan2asn1c(const ITS__Container::CauseCode&t, CauseCode& a)
{
	T2A(causeCode);
	T2A(subCauseCode);
}
ITS__Container::CauseCode         asn1c2titan(const CauseCode& a)
{
	return ITS__Container::CauseCode(
		A2T(causeCode),
		A2T(subCauseCode)
		);
}

// TrafficRule
void                              titan2asn1c(const ITS__Container::TrafficRule&t, long& a)
{
	a = t.as_int();
}


// PtActivation
void                              titan2asn1c(const ITS__Container::PtActivation&t, PtActivation& a)
{
	T2A(ptActivationType);
	T2A(ptActivationData);
}
ITS__Container::PtActivation      asn1c2titan(const PtActivation& a)
{
	return ITS__Container::PtActivation(
		A2T(ptActivationType),
		A2T(ptActivationData)
	);
}

//
void titan2asn1c(const ITS__Container::HardShoulderStatus&t, HardShoulderStatus_t& a)
{
	a = t.as_int();
}

//ClosedLanes
void                              titan2asn1c(const ITS__Container::ClosedLanes&t, ClosedLanes& a)
{
	T2A_O(hardShoulderStatus);
	T2A(drivingLaneStatus);
}
ITS__Container::ClosedLanes       asn1c2titan(const ClosedLanes& a)
{
	return ITS__Container::ClosedLanes(
		A2T_O(ITS__Container::HardShoulderStatus, hardShoulderStatus),
		A2T(drivingLaneStatus)
		);
}

void titan2asn1c(const ITS__Container::PosConfidenceEllipse&t, PosConfidenceEllipse& a)
{
	T2A(semiMajorConfidence);
	T2A(semiMinorConfidence);
	T2A(semiMajorOrientation);
}
ITS__Container::PosConfidenceEllipse asn1c2titan(const PosConfidenceEllipse& a)
{
	return ITS__Container::PosConfidenceEllipse(
		A2T(semiMajorConfidence),
		A2T(semiMinorConfidence),
		A2T(semiMajorOrientation)
		);
}

void titan2asn1c(const ITS__Container::AltitudeConfidence&t, AltitudeConfidence_t& a)
{
	a = t.as_int();
}

void titan2asn1c(const ITS__Container::Altitude&t, Altitude& a)
{
	T2A(altitudeValue);
	T2A(altitudeConfidence);
}

ITS__Container::Altitude asn1c2titan(const Altitude& a)
{
	return ITS__Container::Altitude(
		A2T(altitudeValue),
		asn1c2titan<AltitudeConfidence>(a.altitudeConfidence)
		);
}
