var DataFunctions = {
	loaded: false,
	mass: false,
	units: 'kilogrammes',
	timescale: 'year',
	multiplier: 1,
	absolute: true,
	external_scaling: false,
	scaling: {
		second: Date.years(1),
		day: 364,
		year: 1
	},

	load: function(callback) {
		if (!this.loaded) {
			var loaded = (function(data) {
				return function(mass) {
					data.loaded = true;
					data.mass = mass;
					if(!data.kilogrammes) {
						data.kilogrammes = mass.kilogrammes;
					}
					callback.call(data, data)
				}
			})(this);
			CQ[this.units](this.reference_mass(), loaded);
		} else {
			callback.call(this, this);
		}
	},
	patch_dimension: function() {
		return this.mass.patch[this.timescale].dimension;
	},
	patch_area: function() {
		console.log(this.timescale)
		return this.mass.patch[this.timescale].area;
	},
	angular_size: function() {
		return this.mass.patch[this.timescale].angular_size;
	},
	patch_depth: function() {
		return this.mass.patch[this.timescale].depth;
	},
	opacity: function() {
		var power = -(Math.log(this.patch_depth() / 3.1)/Math.log(10))
		var opacity = 0.9 - (Math.limit(0, power, 9)/9);
		return Math.limit(0.2, opacity, 0.85);
	},
	percentage: function() {
		return this.mass.percentage[this.timescale];
	},
	volume: function() {
		return this.mass.volume;
	},
	sphere: function() {
		return this.mass.sphere;
	},
	cube: function() {
		return this.mass.cube;
	},
	kilotonnes: function() {
		return this.mass.kilotonnes;
	},
	// for some reason ie objects to you overwriting this particular toString method
	// so i've called it to_s instead
	to_s: function() {
		return this.real_mass().to_mass().toString() + ' of '+ CQ.Substance.co2;
	},

	reference_mass: function() {
		return this.real_mass();
	},
	real_mass: function() {
		return (this.kilogrammes * this.multiplier);
	},
	scale: function(multiplier, timescale) {
		mass = this.clone();
		mass.set_scale(multiplier, timescale);
		return mass;
	},
	set_scale: function(multiplier, timescale) {
		this.multiplier = multiplier;
		this.timescale = timescale;
	}
};

function UserEmission(quantity, units) {
	this.quantity = quantity;
	this.units = units;
};

UserEmission.prototype = {};
Object.extend(UserEmission.prototype, DataFunctions, {
	db: false,
	set_scale: function(multiplier, timescale) {
		this.timescale = timescale;
	},
	real_mass: function() {
		return this.quantity;
	},
	to_s: function() {
		var u = this.units, s = 'co2', p = this.units.split(/_/);
		if(p.length > 1) {
			u = p[0];
			s = p[2];
		}
		return this.quantity.human(2) + ' ' + u + ' of '+ CQ.Substance[s];
	},
	type: function() {
		return UserEmission;
	},
	clone: function() {
		return new UserEmission(this.quantity, this.units);
	}
});

function FixedEmission(kilogrammes, source) {
	this.kilogrammes = kilogrammes;
	this.units = 'kilogrammes';
	this.source = source;
};

FixedEmission.prototype = {};
Object.extend(FixedEmission.prototype, DataFunctions, {
	type: "FixedEmission",
	db: true,
	reference_value: function() {
		return {
			value: this.kilogrammes,
			units: 'kilogrammes'
		};
	},
	percentage: function() {
		return this.mass.percentage[this.timescale];
	},
	patch_depth: function() {
		return this.mass.patch[this.timescale].depth;
	},
	type: function() {
		return FixedEmission;
	},
	clone: function() {
		return new FixedEmission(this.kilogrammes, this.source);
	}
});

function AnnualEmission(kilogrammes, source) {
	this.kilogrammes = kilogrammes;
	this.source = source;
};

AnnualEmission.prototype = {};
Object.extend(AnnualEmission.prototype, DataFunctions, {
	absolute: false,
	external_scaling: true,
	type: "AnnualEmission",
	db: true,
	scale: function(multiplier, timescale) {
		mass = this[timescale]();
		mass.set_scale(multiplier, timescale);
		return mass;
	},
	year: function() {
		return new AnnualEmission(this.kilogrammes, this.source);
	},
	day: function() {
		return new AnnualEmission(this.kilogrammes/this.scaling.day, this.source);
	},
	second: function() {
		return new AnnualEmission(this.kilogrammes/this.scaling.second, this.source);
	},
	reference_value: function() {
		return this.year();
	},
	percentage: function() {
		return this.mass.percentage[this.timescale];
	},
	patch_dimension: function() {
		return this.mass.patch[this.timescale].dimension;
	},
	patch_area: function() {
		return this.mass.patch[this.timescale].area;
	},
	angular_size: function() {
		return this.mass.patch[this.timescale].angular_size;
	},
	patch_depth: function() {
		return this.mass.patch[this.timescale].depth * this.multiplier;
	},
	volume: function() {
		return this.mass.volume * this.mass.percentage[this.timescale];
	},
	reference_mass: function() {
		return this.kilogrammes;
	},
	real_mass: function() {
		return (this.kilogrammes * this.multiplier);
	},
	type: function() {
		return AnnualEmission;
	},
	clone: function() {
		return new AnnualEmission(this.kilogrammes, this.source);
	}
});

var PartsPerMillion = function(ppm) {
	this.ppm = ppm || 1;
	this.multiplier = this.ppm;
};
PartsPerMillion.prototype = {};
Object.extend(PartsPerMillion.prototype, DataFunctions, {
	type: "PartsPerMillion",
	units: 'ppm',
	db: true,
	absolute: true,
	external_scaling: true,
	source: '<a href="http://cdiac.ornl.gov/faq.html#Q6">CDIAC</a>',
	percentage: function() {
		return 1;
	},
	patch_dimension: function() {
		return this.mass.patch.second.dimension;
	},
	patch_area: function() {
		return this.mass.patch.second.area;
	},
	angular_size: function() {
		return this.mass.patch.second.angular_size;
	},
	patch_depth: function() {
		return this.mass.depth
	},
	type: function() {
		return PartsPerMillion;
	},
	clone: function() {
		return new PartsPerMillion(this.ppm);
	},
	reference_mass: function() {
		return this.ppm;
	},
	real_mass: function() {
		return this.mass.kilogrammes;
	},
	set_scale: function(multiplier, timescale) {
		this.ppm = multiplier;
		this.multiplier = multiplier;
		this.timescale = 'year';
	},
	to_s: function() {
		return this.mass.kilogrammes.to_mass() + ' of '+ CQ.Substance.co2;
	}
});

var sources = {
	unknown: '',
	all_the_co2: '<a href="http://cdiac.ornl.gov/ftp/trends/co2/maunaloa.co2">Atmospheric CO2 values (ppmv) derived from in situ air samples collected at Mauna Loa, Hawaii, USA</a>',
	world_emissions: '<a href="http://cdiac.ornl.gov/trends/emis/tre_glob.html">doi 10.3334/CDIAC/00001 (World)</a>',
	xxx: '<a href="http://somethingelse.com">some :ource</a>',
	yyy: '<a href="http://somethingelse.com">some other source</a>',
	zzz: '<a href="http://zzz.com">yet another source</a>',
	carbon_trust_factsheet: function(product_id) {
		return '<a href="http://www.carbontrust.co.uk/publications/publicationdetail.htm?productid='+product_id+'">Carbon Trust Fact Sheet CTL018, Energy and carbon conversions, 2008 update</a>';
	},
	drax: '<a href="http://www.draxgroup.plc.uk/files/financialreport/44948/Drax_Group_plc_Annual_Report_2007.pdf">Drax Group plc Annual Report 2007</a>',
	cdiac: function(code) {
		var page = (code === 'som' || code === 'ban') ? code : 'tre_' + code;
		var country = code.toUpperCase();
		if(code=== 'glob') {
			country = 'World';
		}
		if(code === 'uk') {
			page += 'i';
		}
		return '<a href="http://cdiac.ornl.gov/trends/emis/'+page+'.html">doi 10.3334/CDIAC/00001 ('+country+')</a> - Emissions from fossil fuels and cement manufacture.';
	},
	defra: '<a href="http://www.defra.gov.uk/environment/statistics/globatmos/galocalghg.htm">Defra, Sept. 2008, Local and Regional CO2 Emissions Estimates for 2005 - 2006 for the UK</a>'
};

// lookup to convert geoip country codes to the cdiac ones
var geo_ip = {
	'AU': 'aus',
	'BD': 'ban',
	'CA': 'can',
	'CN': 'prc',
	'DE': 'ger',
	'IN': 'ind',
	'IT': 'ita',
	'JP' : 'jap',
	'RU' : 'rus',
	'SO' : 'som',
	'KR' : 'sok',
	'GB' : 'uk',
	'US' : 'usa'
}
var data = {
	ppm: new PartsPerMillion(1),

	all_the_co2: {
		'2008': new FixedEmission(3009.5054e+12, sources.all_the_co2),
		'2007': new FixedEmission(2995.5255e+12, sources.all_the_co2),
		'2006': new FixedEmission(2982.1704e+12, sources.all_the_co2),
		'2005': new FixedEmission(2965.2227e+12, sources.all_the_co2),
		'2004': new FixedEmission(2947.3378e+12, sources.all_the_co2),
		'2003': new FixedEmission(2933.7484e+12, sources.all_the_co2),
		'2002': new FixedEmission(2913.911e+12, sources.all_the_co2),
		'2001': new FixedEmission(2897.6662e+12, sources.all_the_co2),
		'2000': new FixedEmission(2885.6388e+12, sources.all_the_co2),
		'1999': new FixedEmission(2876.5011e+12, sources.all_the_co2),
		'1998': new FixedEmission(2863.3803e+12, sources.all_the_co2),
		'1997': new FixedEmission(2840.9656e+12, sources.all_the_co2),
		'1996': new FixedEmission(2832.2184e+12, sources.all_the_co2),
		'1995': new FixedEmission(2818.4728e+12, sources.all_the_co2),
		'1994': new FixedEmission(2802.9309e+12, sources.all_the_co2),
		'1993': new FixedEmission(2788.4824e+12, sources.all_the_co2),
		'1992': new FixedEmission(2783.2497e+12, sources.all_the_co2),
		'1991': new FixedEmission(2777.1579e+12, sources.all_the_co2),
		'1990': new FixedEmission(2766.2239e+12, sources.all_the_co2),
		'1989': new FixedEmission(2756.2271e+12, sources.all_the_co2),
		'1979': new FixedEmission(2630.7985e+12, sources.all_the_co2),
		'1969': new FixedEmission(2535.3603e+12, sources.all_the_co2),
		'1959': new FixedEmission(2467.8038e+12, sources.all_the_co2),
		'1750': new FixedEmission(2186.8e+12, sources.all_the_co2)
	},

	world_emissions: new AnnualEmission(30176666.67e+6, sources.world_emissions),

	energy_generation_emissions: {
		uk_grid: new FixedEmission(0.537, sources.carbon_trust_factsheet('CTL018')),
		drax: new FixedEmission(0.84, sources.drax),
		natural_gas: new FixedEmission(0.185, sources.carbon_trust_factsheet('CTL019')),
		industrial_coal: new FixedEmission(0.33, sources.carbon_trust_factsheet('CTL020')),
		fuel_oil: new FixedEmission(0.268, sources.carbon_trust_factsheet('CTL021')),
		wood_pellets: new FixedEmission(0.025, sources.carbon_trust_factsheet('CTL024')),
		diesel: new FixedEmission(0.25, sources.carbon_trust_factsheet('CTL022')),
		petrol: new FixedEmission(0.24, sources.carbon_trust_factsheet('CTL023')),
		lpg: new FixedEmission(0.214, sources.carbon_trust_factsheet('CTL024'))
	},
	national_emissions: {
		afr: new AnnualEmission(1067931.333e+6, sources.cdiac('afr')),
		aus: new AnnualEmission(372012.6667e+6, sources.cdiac('aus')),
		ban: new AnnualEmission(41609.33333e+6, sources.cdiac('ban')),
		can: new AnnualEmission(544679.6667e+6, sources.cdiac('can')),
		amd: new AnnualEmission(1514362.667e+6, sources.cdiac('amd')),
		prc: new AnnualEmission(6103493.0e+6, sources.cdiac('prc')),
		ger: new AnnualEmission(805090.0e+6, sources.cdiac('ger')),
		ind: new AnnualEmission(1510351.333e+6, sources.cdiac('ind')),
		ita: new AnnualEmission(474147.6667e+6, sources.cdiac('ita')),
		jap: new AnnualEmission(1293409.333e+6, sources.cdiac('jap')),
		rus: new AnnualEmission(1564669.333e+6, sources.cdiac('rus')),
		som: new AnnualEmission(172.3333333e+6, sources.cdiac('som')),
		sok: new AnnualEmission(475247.6667e+6, sources.cdiac('sok')),
		uk: new AnnualEmission(568520.3333e+6, sources.cdiac('uk')),
		usa: new AnnualEmission(5752288.667e+6, sources.cdiac('usa')),
		glob: new AnnualEmission(30176666.67e+6, sources.cdiac('glob'))
	},

	percapita_emissions: {
		afr: new AnnualEmission(1.1e+3, sources.cdiac('afr')),
		aus: new AnnualEmission(17.96666667e+3, sources.cdiac('aus')),
		ban: new AnnualEmission(0.293333333e+3, sources.cdiac('ban')),
		can: new AnnualEmission(16.68333333e+3, sources.cdiac('can')),
		amd: new AnnualEmission(2.713333333e+3, sources.cdiac('amd')),
		prc: new AnnualEmission(4.656666667e+3, sources.cdiac('prc')),
		ger: new AnnualEmission(9.79e+3, sources.cdiac('ger')),
		ind: new AnnualEmission(1.356666667e+3, sources.cdiac('ind')),
		ita: new AnnualEmission(8.03e+3, sources.cdiac('ita')),
		jap: new AnnualEmission(10.26666667e+3, sources.cdiac('jap')),
		rus: new AnnualEmission(10.96333333e+3, sources.cdiac('rus')),
		som: new AnnualEmission(0.036666667e+3, sources.cdiac('som')),
		sok: new AnnualEmission(9.826666667e+3, sources.cdiac('sok')),
		uk: new AnnualEmission(9.386666667e+3, sources.cdiac('uk')),
		usa: new AnnualEmission(18.99333333e+3, sources.cdiac('usa')),
		glob: new AnnualEmission(4.583333333e+3, sources.cdiac('glob'))
	},

	uk_regional: {
		gln: new AnnualEmission(49614.29131e+6, sources.defra),
		car: new AnnualEmission(2355.466372e+6, sources.defra),
		edn: new AnnualEmission(3260.505008e+6, sources.defra),
		bel: new AnnualEmission(2234.599132e+6, sources.defra),
		bri: new AnnualEmission(2305.221571e+6, sources.defra),
		man: new AnnualEmission(3356.178808e+6, sources.defra),
		ni: new AnnualEmission(16344.24777e+6, sources.defra),
		sco: new AnnualEmission(43492.99311e+6, sources.defra),
		wal: new AnnualEmission(32930.96824e+6, sources.defra),
		eng: new AnnualEmission(434350.1819e+6, sources.defra),
		swe: new AnnualEmission(42368.91423e+6, sources.defra),
		see: new AnnualEmission(66032.72248e+6, sources.defra),
		eoe: new AnnualEmission(45372.1046e+6, sources.defra),
		wme: new AnnualEmission(44898.66508e+6, sources.defra),
		eme: new AnnualEmission(40800.4941e+6, sources.defra),
		yoe: new AnnualEmission(53276.30942e+6, sources.defra),
		nwe: new AnnualEmission(59454.93167e+6, sources.defra),
		nee: new AnnualEmission(32531.74899e+6, sources.defra)
	},
	big_emitters: {
		drax: new AnnualEmission(21168.0e+6, sources.drax)
	},

	co2_per_litre: {
		petrol:new FixedEmission(2.315,  sources.carbon_trust_factsheet('CTL024')),
		diesel:new FixedEmission(2.63, sources.carbon_trust_factsheet('CTL025')),
		lpg:new FixedEmission(1.495, sources.carbon_trust_factsheet('CTL026'))
	},

	co2_per_kilometre: {
		small_petrol_car: new FixedEmission(0.1809, sources.carbon_trust_factsheet('CTL026')),
		average_petrol_car: new FixedEmission(0.207, sources.carbon_trust_factsheet('CTL027')),
		large_petrol_car: new FixedEmission(0.258, sources.carbon_trust_factsheet('CTL028')),
		average_diesel_car: new FixedEmission(0.1979, sources.carbon_trust_factsheet('CTL029')),
		taxi: new FixedEmission(0.1593, sources.carbon_trust_factsheet('CTL030')),
		average_bus_or_coach: new FixedEmission(0.0686, sources.carbon_trust_factsheet('CTL031')),
		eurostar: new FixedEmission(0.0177, sources.carbon_trust_factsheet('CTL032')),
		uk_national_rail: new FixedEmission(0.0602, sources.carbon_trust_factsheet('CTL033')),
		light_rail: new FixedEmission(0.078, sources.carbon_trust_factsheet('CTL034')),
		underground: new FixedEmission(0.065, sources.carbon_trust_factsheet('CTL035')),
		longhaul_flight: new FixedEmission(0.1206, sources.carbon_trust_factsheet('CTL036')),
		shorthaul_flight: new FixedEmission(0.1071, sources.carbon_trust_factsheet('CTL037')),
		domestic_flight: new FixedEmission(0.1911, sources.carbon_trust_factsheet('CTL038'))
	}
};




