var substancesRegistry = new Array();
var toxClassesRegistry = new Array();
var substancesArray = new Array() ;
var binaryInteractionsRegistry = new Array();
var PELSourcesRegistry = new Array() ;

var gblPOW2Max = 50 ;
var gblPOW2 = new Array() ;
for ( var i = 0 ; i < gblPOW2Max ; i++) 
{
	gblPOW2[i] = Math.pow(2,i) ;
}

function getPELSourceById(psid)
{
	return PELSourcesRegistry[psid] ;
}


function getToxClassById( cid)
{
	
	return toxClassesRegistry[cid] ;
}

function getSubstanceById( sid)
{
	return substancesRegistry[sid] ;
}

function getBinaryInteractionsBySubstanceIds( sid1, sid2)
{
	var ans = binaryInteractionsRegistry[sid1] ;
	if ( ans )
		ans = ans[sid2] ;
	return ans ;
}


function BI(s1_id, s2_id, ic, externalReference, analysis, conclusion)
{
	// Binary interaction class
	this.s1_id = s1_id ;	// id of first substance
	this.s2_id = s2_id ;	// id of second substance
	this.ic = ic ;			// category of interaction
	this.externalReference = externalReference ;  // info that permits to locate an external file which gives info about the interaction
	this.analysis = analysis ;  // text
	this.conclusion = conclusion ; // text 
	// register the interaction
	if(! binaryInteractionsRegistry[s1_id])
		binaryInteractionsRegistry[s1_id] = new Array() ;
	if(! binaryInteractionsRegistry[s2_id])
		binaryInteractionsRegistry[s2_id] = new Array() ;
	
	binaryInteractionsRegistry[s1_id][s2_id] = this ;
	binaryInteractionsRegistry[s2_id][s1_id] = this ;
}

function BIC( id, name )
{
	// Binary interaction category class
	this._id = id ; // id
	this.name = name ; // category name
}

function Unit( id, weight, abr )
{
	// Measure unit class
	this._id = id ; // id
	this.abr = abr ; // abreviation (ppm ...)
	this.weight = weight ; // mgm3, ppm, f/cm³
}

function ToxClass( id, name )
{
	// 'Toxicological interactions class' class
	this._id = id ; // id
	this.name = name ; // class name // correction _name
	toxClassesRegistry[this._id] = this ;  // Ajout
}

function PELType( id, weight, abr )
{
	// PELType class
	this._id = id ; // id
	this.weight = weight ;  // use in pels combo; twa, stel, ceiling
	this.abr = abr ; // abreviation used
}

function PELSource( id, abr, definition )
{
	// PELType class
	this._id = id ; // id
	this.abr = abr ;  // use in pels combo; twa, stel, ceiling
	this.definition = definition ; // abreviation used
	PELSourcesRegistry[id] = this ;
}

function PEL( pelType, val, unit)
{
	// PEL class
	this.pelType = pelType ;  // twa, stel, ceiling ?
	this.value = val ; // numerical value
	this.unit = unit ; // unit of measure
}

function ToxClassesBin(toxClasses)
{

	this.bin = new Array() ;
	this.bin[0] = 0 ;
	this.bin[1] = 0 ; 
	var indice ;
	
	if(arguments.length > 0 )
	{
		for ( var i = 0 ; i < toxClasses.length ; i++ )
		{
			indice = Math.floor(toxClasses[i]._id / 30) ;
			this.bin[indice] |= Math.pow(2,toxClasses[i]._id  - ( 30 * indice) ) ;
		}
	}
	this.AND = AND ;
	this.OR = OR ;
	this.asString = asString ;
	this.toArray = toArray ;
	this.isEmpty = isEmpty ;

	
	function AND( tc) 
	{
//		alert('and');
		var rep = new ToxClassesBin() ;
		rep.bin[0] =  this.bin[0] & tc.bin[0] ;
		rep.bin[1] = this.bin[1] & tc.bin[1] ;
//		alert('AND' + rep.asString()) ;
		return rep ;
	}
	
	function OR( tc) 
	{
		var rep = new ToxClassesBin() ;
		rep.bin[0] =  this.bin[0] | tc.bin[0] ;
		rep.bin[1] = this.bin[1] | tc.bin[1] ;
		return rep ;
	}

	function isEmpty()
	{
		return ( this.bin[0] + this.bin[1] ) == 0  ;
	}
	
	function asString()
	{
		var rep = '' ;
		var j = 0;
		
		for ( var i_0 = 0 ; i_0 < this.bin.length ; i_0++)
		{	
			j = 0 ;
			for ( var i_1 = 0 ;  j <= this.bin[i_0] ; i_1++ )
			{
				j = gblPOW2[i_1] ;
				if (( this.bin[i_0] & j ) != 0)
				{
					rep+= 'C' + (i_1 + ( i_0 * 30 )) + ' ' ;
				}
			}
		}
		return  rep ;
	}
	function toArray( )
	{
		/*
		 Transforme un nombre concu comme un masque en un array
		 Par exemple 3 = 11 donne une 1 et 2 alors que 4 = 100 donne 3
		*/
		var rep = new Array() ;
	
		var j = 0 ;

		for ( var i_0 = 0 ; i_0 < this.bin.length ; i_0++)
		{		
			j = 0 ;
			for ( var i_1 = 0 ;  j <= this.bin[i_0] ; i_1++ )
			{
				j = gblPOW2[i_1] ;
				if (( this.bin[i_0] & j ) != 0)
				{
					rep[rep.length] = i_1 + ( i_0 * 30 );
				}
			}
		}
		return rep ;
	}
}

function Substance(id, _externalReference, name, pels, toxClasses, isCarcinogenic,PELSource_id)
{
	// substance class
	this._id = id ; // id
	
	this.externalReference = _externalReference ;  // ref to pdf file
	this.name = name ; // susbstance name
	this.pels = pels ; // array of pels, may be empty []
	this.toxClasses = toxClasses ; // array of toxicological interactions classes
	this.toxClassesBin = new ToxClassesBin(toxClasses) ;
	this.isCarcinogenic = isCarcinogenic ; // a boolean 
	this.PELSource_id = PELSource_id ;
	substancesRegistry[id] = this ; // we register the substance 
	
	this.arrayIndex = substancesArray.length ; // ajout
	substancesArray[this.arrayIndex] = this ; // ajout

}


