var preset = new Array();

/* Channel Plan */

function ChannelPlan(bandwidth, central_frequency_channel_0, first_channel, last_channel) {
	this.bandwidth = parseInt(bandwidth);
	this.central_frequency_channel_0 = parseInt(central_frequency_channel_0);
	this.first_channel = parseInt(first_channel);
	this.last_channel = parseInt(last_channel);
}

ChannelPlan.prototype.bandwidth;
ChannelPlan.prototype.getBandwidth = function() { return this.bandwidth; };
ChannelPlan.prototype.setBandwidth = function(bandwidth) { this.bandwidth = bandwidth; };

ChannelPlan.prototype.central_frequency_channel_0;
ChannelPlan.prototype.getCentralFrequencyChannel0 = function() { return this.central_frequency_channel_0; };
ChannelPlan.prototype.setCentralFrequencyChannel0 = function(central_frequency_channel_0) { this.central_frequency_channel_0 = central_frequency_channel_0; };

ChannelPlan.prototype.first_channel;
ChannelPlan.prototype.getFirstChannel = function() { return this.first_channel; };
ChannelPlan.prototype.setFirstChannel = function(first_channel) { this.first_channel = first_channel; };

ChannelPlan.prototype.last_channel;
ChannelPlan.prototype.getLastChannel = function() { return this.last_channel; };
ChannelPlan.prototype.setLastChannel = function(last_channel) { this.last_channel = last_channel; };

ChannelPlan.prototype.getCentralFrequency = function(channel) {
	return this.central_frequency_channel_0 + channel * this.bandwidth;
};

ChannelPlan.prototype.getChannel = function(frequency) {
	return Math.round((frequency - this.central_frequency_channel_0) / this.bandwidth);
};

ChannelPlan.prototype.getOffset = function(frequency) {
	return (frequency - this.central_frequency_channel_0) % this.bandwidth;
};

ChannelPlan.prototype.isWithinRange = function(channel) {
	return channel >= this.first_channel && channel <= this.last_channel;
};

ChannelPlan.prototype.isFrequencyWithinRange = function(frequency) {
	return this.isWithinRange(this.getChannel(frequency));
};

ChannelPlan.prototype.equals = function(reference) {
	var result =
		this.bandwidth == reference.bandwidth &&
		this.central_frequency_channel_0 == reference.central_frequency_channel_0 &&
		this.first_channel == reference.first_channel &&
		this.last_channel == reference.last_channel;
	return result;
};

preset["cp"] = new Array();
preset["cp"]["europe"] = new ChannelPlan(8000000, 306000000, 21, 69);
preset["cp"]["america"] = new ChannelPlan(6000000, 389000000, 14, 83);
preset["cp"]["australia"] = new ChannelPlan(7000000, 334500000, 28, 69);

/* Transmission parameters */

function TransmissionParameters(bandwidth, coderate, guard_interval, mode, modulation) {
	this.bandwidth = parseInt(bandwidth);
	this.coderate = parseFloat(coderate);
	this.guard_interval = parseFloat(guard_interval);
	this.mode = parseInt(mode);
	this.modulation = modulation;
	
	this.coderate_lp = 1;
}

TransmissionParameters.prototype.bandwidth;
TransmissionParameters.prototype.getBandwidth = function() { return this.bandwidth; };
TransmissionParameters.prototype.setBandwidth = function(bandwidth) { this.bandwidth = bandwidth; };

TransmissionParameters.prototype.coderate;
TransmissionParameters.prototype.getCodeRate = function() { return this.coderate; };
TransmissionParameters.prototype.setCodeRate = function(coderate) { this.coderate = coderate; };

TransmissionParameters.prototype.guard_interval;
TransmissionParameters.prototype.getGuardInterval = function() { return this.guard_interval; };
TransmissionParameters.prototype.setGuardInterval = function(guard_interval) { this.guard_interval = guard_interval; };

TransmissionParameters.prototype.mode;
TransmissionParameters.prototype.getMode = function() { return this.mode; };
TransmissionParameters.prototype.setMode = function(mode) { this.mode = mode; };

TransmissionParameters.prototype.modulation;
TransmissionParameters.prototype.getModulation = function() { return this.modulation; };
TransmissionParameters.prototype.setModulation = function(modulation) { this.modulation = modulation; };
TransmissionParameters.prototype.getModulationBitrateParam = function(priotity) {
	var c = 0;
	switch (this.modulation) {
	case "QPSK":
		c = 0;
		break;
	case "16-QAM":
		c = 1;
		break;
	case "64-QAM":
		c = 2;
		break;
	}
	switch (priotity) {
	case "none": return 2 * (c + 1);
	case "HP": return 1;
	case "LP": return 2 * c;
	default: return 0;
	}
};

TransmissionParameters.prototype.coderate_lp;
TransmissionParameters.prototype.getCodeRateLP = function() { return this.coderate_lp; };
TransmissionParameters.prototype.setCodeRateLP = function(coderate_lp) { this.coderate_lp = coderate_lp; };

TransmissionParameters.prototype.getBitrate = function(packet_size, priotity) {
	var cr = (priotity == "LP") ? this.coderate_lp : this.coderate;
	var ja = 6048 * this.getModulationBitrateParam(priotity) * cr * packet_size / 204;
	var ka = (7 / 64000000) * 8000000 / this.bandwidth * (8192 * (1 + this.guard_interval));
	return ja / ka;
};

TransmissionParameters.prototype.getBitrateNone = function() {
	return this.getBitrate(188, "none");
};

TransmissionParameters.prototype.getBitrateHP = function() {
	return this.getBitrate(188, "HP");
};

TransmissionParameters.prototype.getBitrateLP = function() {
	return this.getBitrate(188, "LP");
};

TransmissionParameters.prototype.getUsefulSymbolDuration = function() {
	var qa = 7 / (8 * this.bandwidth);
	var ra = 1024 * this.mode;
	return ra * qa;
};

TransmissionParameters.prototype.getGuardIntervalDuration = function() {
	return this.getUsefulSymbolDuration() * this.guard_interval;
};

TransmissionParameters.prototype.getSymbolDuration = function() {
	return this.getUsefulSymbolDuration() + this.getGuardIntervalDuration();
};

TransmissionParameters.prototype.equals = function(reference) {
	var result =
		(this.bandwidth == reference.bandwidth &&
		this.coderate == reference.coderate &&
		this.coderate_lp == reference.coderate_lp &&
		this.guard_interval == reference.guard_interval &&
		this.mode == reference.mode &&
		this.modulation == reference.modulation);
	return result;
};

preset["tp"] = new Array();
preset["tp"]["spain"] = new TransmissionParameters(8000000, 2/3, 1/4, 8, "64-QAM");
preset["tp"]["france"] = new TransmissionParameters(8000000, 2/3, 1/32, 8, "64-QAM");
preset["tp"]["andorra"] = new TransmissionParameters(8000000, 2/3, 1/8, 8, "64-QAM");
//preset["tp"]["colombia"] = new TransmissionParameters(8000000, 2/3, 1/8, 8, "64-QAM");

/* Misc */

function dBm2dBuV(dbm) {
	var zc = 75;
    var p = Math.pow(10, dbm / 10) / 1000;
    var u = Math.sqrt(p * zc);
    return 20 * Math.log(u * 1000000) / Math.LN10 ;
}

function dBuV2dBm(dbuv) {
	var zc = 75;
    var u = Math.pow(10, dbuv / 20) / 1000000;
    var p = (u * u) / zc;
    return 10 * Math.log(p * 1000) / Math.LN10;
}

