function [outstruct,mineralstruct] = loadbackground(controlstruct)
%outstruct,mineralstruct] = loadbackground(controlstruct)
%loadbackground reads the users mineral model file. This function
%should be called within a try/catch block with whis function
%in the try portion and loadbackgroundexpection in the catch portion
%loadbackground exception provides fairly detailed error messages to the
%user if their are errors in the mineral model file.
%INPUT 
%controlstruct is structure created in APHIDengine that contains
%the basic infromation required to run APHID
%OUTOUT
%outstruct is a structure that contains global information about the 
%transformation
%mineralstruct = is a structure array in which the elements of the
%array are data required for the transformation using the stoichiometric
%model for that mineral
%
%Written by K. Steffen (ksteffen@unm.edu) at the University of New Mexico,
%Department of Earch and Planetary Science and copyrighted under the GNU
%public license, see APHID.m and www.gnu.org for details
%
%Last Modified June 13, 2003

file = controlstruct.backgroundfile;
FID = fopen(file,'r');

tempstring = fgetl(FID);	
Elements = ParseLine(tempstring);  %List of Elements to be considered
tempstring = fgetl(FID);
tempstring = fgetl(FID);
Minerals = ParseLine(tempstring);  %List of Minerals to be considered
keeptrack = zeros(1,length(Minerals));
tempstring = fgetl(FID);
tempstring = fgetl(FID);
GfElement = ParseLine(tempstring);  %element order in oxide to cation conversion
tempstring = fgetl(FID);
GramFormulaList = sscanf(tempstring,'%f',length(GfElement));  %Gramformula Weights

tempstring = fgetl(FID);
CationsList = sscanf(tempstring,'%f',length(GfElement));  %Cations per oxide

tempstring = fgetl(FID);
ChargeList = sscanf(tempstring,'%f',length(GfElement)); %Charge of cation
tempstring = fgetl(FID);
tempstring = fgetl(FID);
		
%Reading the additive exchange vector labels and matrix
AdditiveExchangeVector = ParseLine(tempstring); %Names of additive and exchange vectors

AdditiveExchange = length(AdditiveExchangeVector);
AdditiveComponentsMaster = 0;

%removing additive components (additive components always end with 'Add' and are listed first
for k = 1:AdditiveExchange
	temp = length(AdditiveExchangeVector{k});
	if temp > 3
		if strncmp('Add',AdditiveExchangeVector{k}(end-2:end),3)
			AdditiveComponentsMaster = AdditiveComponentsMaster + 1; %Names of Additive Components
		end
	end
end


ExchangeComponentsMaster = AdditiveExchange-AdditiveComponentsMaster;

tempstring = fgetl(FID);

%reading cation/additive to exchange/additive matrix and row label (cations)

counter = 1;
if strncmp(sscanf(tempstring,'%s',1),'*',1)
	test = 1;
else
	test = 0;
	AMaster = zeros(1,AdditiveExchange);
	CationAdditiveVector = cell(0);
end

while( test == 0)
	[temp,crap,crap,nextindex] = sscanf(tempstring,'%d',AdditiveExchange);
	AMaster(counter,:) = temp';
	CationAdditiveVector(counter) = {sscanf(tempstring(nextindex:end),'%s')};
	tempstring = fgetl(FID);
	counter = counter  + 1;
	if strncmp(sscanf(tempstring,'%s',1),'*',1)
		test = 1;
	end
end

CationComponentsMaster = counter-AdditiveComponentsMaster-1;
outstruct = struct(...
	'AMaster',{AMaster},...
	'CationAdditiveVector',{CationAdditiveVector},...
	'AdditiveExchangeVector',{AdditiveExchangeVector},...
	'Elements',{Elements},...
	'Minerals',{Minerals},...
	'GfElement',{GfElement},...
	'GramFormulaList',{GramFormulaList},...
	'CationsList',{CationsList},...
	'ChargeList',{ChargeList});
%Finished with overall data, now reading data for each mineral model

test = 0;
while( test == 0)
	tempstring = fgetl(FID);
	MineralName = sscanf(tempstring,'%s'); %Mineral Name

	tempstring = fgetl(FID);
	CationComponents = sscanf(tempstring,'%f',1); %Number of Cation Components

	tempstring = fgetl(FID);
	AdditiveComponents = sscanf(tempstring,'%f',1); %Number of Additive Components

	tempstring = fgetl(FID);
	ExchangeComponents = sscanf(tempstring,'%f',1); %Number of Exchange components

	tempstring = fgetl(FID);
	EndMembers = sscanf(tempstring,'%f',1); %Number of Endmembers
	
	tempstring = fgetl(FID);
	IronOxidation = sscanf(tempstring,'%f',1); %Fe oxidation state

	tempstring = fgetl(FID);
	NumberOxygen = sscanf(tempstring,'%f',1); %Number of oxygens for a probe analysis

	tempstring = fgetl(FID);
	NumberOxygenHyd = sscanf(tempstring,'%f',1); %Number of oxygens on a hydrous basis

	A = zeros(CationComponents+AdditiveComponents,AdditiveComponents+ExchangeComponents);
	order = cell(1,CationComponents+AdditiveComponents);
	D = zeros(1,CationComponents+AdditiveComponents);
	C = cell(2,AdditiveComponents);
	EndMemberVector = cell(1,EndMembers);
	ThisAdditiveExchangeVector = cell(1,AdditiveComponents+ExchangeComponents);
	EndBase = zeros(1,EndMembers);
	EndMemberConversion = zeros(AdditiveComponents+ExchangeComponents,EndMembers);
	EndMemberCations = zeros(EndMembers,CationComponents);

	tempstring = ClearComment(tempstring,FID);
	ThisAdditiveExchangeVector = ParseLine(tempstring);  %The additive and exchange components for this phase

	tempstring = fgetl(FID);
    	upperlimit  = sscanf(tempstring,'%f',AdditiveComponents+ExchangeComponents)'; %upper limit on component values

    	tempstring = fgetl(FID);
    	lowerlimit  = sscanf(tempstring,'%f',AdditiveComponents+ExchangeComponents)'; %lower limit on component values

	tempstring = ClearComment(tempstring,FID);
	ThisCationVector = ParseLine(tempstring); %Cation and additive components

	tempstring = fgetl(FID);
	D = sscanf(tempstring,'%f',AdditiveComponents+CationComponents); %weights

	tempstring = fgetl(FID);
	C = sscanf(tempstring,'%f',AdditiveComponents);  %Value of additive components in cation form 
	if length(C) ~= AdditiveComponents
		errorstring = sprintf('Error Reading Additive Value Vector in file %s',file);
		error(errorstring);
	end
	temp = ThisCationVector(end-AdditiveComponents+1:end);
	C = [temp; double2cell(C')];

	
	tempstring = ClearComment(tempstring,FID);
	EndMemberVector = ParseLine(tempstring);  %EndMembers

	tempstring = fgetl(FID);
	EndBase  = sscanf(tempstring,'%f',EndMembers)';


	for k = 1:AdditiveComponents+ExchangeComponents
 		tempstring = fgetl(FID);
		EndMemberConversion(k,:) = sscanf(tempstring,'%f',EndMembers)'; %matrix to convert from additive/exchange
		%to endmember components
	end

	tempstring = ClearComment(tempstring,FID);
	density = [];
	for k = 1:EndMembers
		temp = sscanf(tempstring,'%f',CationComponents+1);
		EndMemberCations(k,:) = temp(1:CationComponents)';  %The endmembers defined as cations
		density(k) = temp(end);
		tempstring = fgetl(FID);
	end

	if tempstring ==  -1
		test = 1;
	else
		if strncmp(sscanf(tempstring,'%s',1),'*',1)
			test = 0;
		else
		test = 1;
		end
	end

	A = zeros(CationComponents+AdditiveComponents,AdditiveComponents+ExchangeComponents);

	columns = GetColumnsGeneral(AdditiveExchangeVector,ThisAdditiveExchangeVector);
	columns = [columns{2,:}];

	rows = GetColumnsGeneral(CationAdditiveVector,ThisCationVector);
	rows = [rows{2,:}];


	Atemp = AMaster(:,columns);
	Atemp = Atemp(rows,:);
	%saving data for this mineral/stoichiometric model
	minoutstruct = struct(...
		'density',density,...
		'MineralName',{MineralName},...
		'A',{Atemp},... 
		'D',{D},...
		'order',{ThisCationVector},...
		'upperlimit',{upperlimit},...
		'lowerlimit',{lowerlimit},...
		'AdditiveExchangeVector',{ThisAdditiveExchangeVector},...
		'EndMemberVector',{EndMemberVector},...
		'EndBase',{EndBase},...
		'EndMemberConversion',{EndMemberConversion},... 
		'C',{C},...
		'NumberEndMembers',{EndMembers},...
		'NumberCationComponents',{CationComponents},...
		'NumberExchangeComponents',{ExchangeComponents},...
		'NumberAdditiveComponents',{AdditiveComponents},...
		'IronOxidation',{IronOxidation},...
		'EndMemberCations',{EndMemberCations},...
		'NumberOxygen',{NumberOxygen},...
		'NumberOxygenHyd',{NumberOxygenHyd});

	index = GetColumnsGeneral3(Minerals,{MineralName});
	index = index{2,1};
	if index ~= -1
		keeptrack(index) = 1;
		mineralstruct(index) = minoutstruct;
	end

end

bad = find(keeptrack == 0);
if ~isempty(bad)
	errorstring = [];
	for k = 1:length(bad)
		errorstring = [errorstring ' ' [Minerals{bad(k)}]]; 
	end
	errorstring = ['Data for the requested mineral(s) ' errorstring ' can not not be found in background file ' sprintf('%s',file)];
	warning(errorstring); 
end

fclose(FID);




