function convertCOBRA2XML(model,fileName,compSymbol,compNameList)
% This function converts a COBRA model (structure format) to *.xml file
% (SBML format). This is an alternate to COBRA2SBML or writeSBMLModel.
% INPUT:
% % model: COBRA model in structure format.
% % compSymbol: list of compartment IDs to be used.
% % compNameList: list of compartment name
% % fileName: Name of *.xml file.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % Written By Chintan Joshi on 7/4/2014 % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

model.S = full(model.S);

l{1} = '<?xml version="1.0" encoding="UTF-8"?>';
l{2} = '<sbml xmlns="http://www.sbml.org/sbml/level2" level="2" version="1">';
l{3} = '<model>';
l{4} = '<listOfUnitDefinitions>';
l{5} = '<unitDefinition id="mmol_per_gDW_per_hr">';
l{6} = '<listOfUnits>';
l{7} = '<unit kind="mole" scale="-3"/>';
l{8} = '<unit kind="gram" exponent="-1"/>';
l{9} = '<unit kind="second" exponent="-1" multiplier="0.000277777777777778"/>';
l{10} = '</listOfUnits>';
l{11} = '</unitDefinition>';
l{12} = '</listOfUnitDefinitions>';
l{13} = '<listOfCompartments>';
for i=1:length(compSymbol)
    comp{i} = ['<compartment id="',compSymbol{i},'" name="',compNameList{i},'"/>'];
end
l{14} = '</listOfCompartments>';
l{15} = '<listOfSpecies>';

for i=1:length(model.mets)
    mets{i,1} = strcat('M_',model.mets{i,1}(1,1:end-3),'_',model.mets{i,1}(1,end-1));
    mets{i,1} = regexprep(mets{i,1},'\(','_LPAREN_');
    mets{i,1} = regexprep(mets{i,1},'\)','_RPAREN_');
    mets{i,1} = regexprep(mets{i,1},'-','_DASH_');
    sp{i,1} = strcat('species id="',mets{i,1},'" name="',model.metNames{i,1},'" compartment="',model.mets{i,1}(1,end-1),'"');
end
m{1} = '<notes>';
m{2} = '<body xmlns="http://www.w3.org/1999/xhtml">';
m{3} = 'FORMULA: ';
m{4} = 'CHARGE: ';
m{5} = '</body>';
m{6} = '</notes>';
m{7} = '</species>';

l{16} = '</listOfSpecies>';
l{17} = '<listOfReactions>';

for i=1:length(model.rxns)
    rx{i,1} = regexprep(model.rxns{i,1},'\(','_LPAREN_');
    rx{i,1} = regexprep(rx{i,1},'\)','_RPAREN_');
    rx{i,1} = regexprep(rx{i,1},'&','&amp;');
    rx{i,1} = regexprep(rx{i,1},'-','_DASH_');
    rxnN{i,1} = regexprep(model.rxnNames{i,1},'\&','&amp;');
    rxnN{i,1} = regexprep(rxnN{i,1},'<=>','&lt;=&gt;');
    rxn{i,1} = strcat('reaction id="R_',rx{i,1},'" name="',rxnN{i,1},'"');
end
spRefStart = '<speciesReference species="';
stoichiometry = '" stoichiometry="';
spRefEnd = '"/>';
r{1} = '<notes>';
r{2} = '<body xmlns="http://www.w3.org/1999/xhtml">';
r{3} = 'GENE_ASSOCIATION: ';
r{4} = 'SUBSYSTEM: ';
r{5} = 'EC Number: ';
r{6} = 'Confidence Level: ';
r{7} = 'AUTHORS: ';
r{8} = '<p/>';
r{9} = '</body>';
r{10} = '</notes>';
r{11} = '<listOfReactants>';
for i=1:size(model.S,2)
    indx = find(model.S(:,i)<0);
    if isempty(indx)
        reacSense(i,1)=0;
    else
        reacSense(i,1)=1;
    end
    for j=1:length(indx)
        react{i,1}{j,1} = strcat(spRefStart,mets{indx(j,1),1},stoichiometry,num2str(model.S(indx(j,1),i)),spRefEnd);
    end
end
r{12} = '</listOfReactants>';
r{13} = '<listOfProducts>';
for i=1:size(model.S,2)
    indx = find(model.S(:,i)>0);
    if isempty(indx)
        prodSense(i,1)=0;
    else
        prodSense(i,1)=1;
    end
    for j=1:length(indx)
        prod{i,1}{j,1} = strcat(spRefStart,mets{indx(j,1),1},stoichiometry,num2str(model.S(indx(j,1),i)),spRefEnd);
    end
end
r{14} = '</listOfProducts>';
r{15} = '<kineticLaw>';
r{16} = '<math xmlns="http://www.w3.org/1998/Math/MathML">';
r{17} = '<ci> FLUX_VALUE </ci>';
r{18} = '</math>';
r{19} = '<listOfParameters>';
for i=1:length(model.lb)
    lb{i,1} = strcat('<parameter id="LOWER_BOUND" value="',num2str(model.lb(i,1)),'" units="mmol_per_gDW_per_hr"/>');
    ub{i,1} = strcat('<parameter id="UPPER_BOUND" value="',num2str(model.ub(i,1)),'" units="mmol_per_gDW_per_hr"/>');
    fv{i,1} = '<parameter id="FLUX_VALUE" value="0" units="mmol_per_gDW_per_hr"/>';
    c{i,1} = strcat('<parameter id="OBJECTIVE_COEFFICIENT" value="',num2str(model.c(i,1)),'" units="mmol_per_gDW_per_hr"/>');
end
r{20} = '</listOfParameters>';
r{21} = '</kineticLaw>';
r{22} = '</reaction>';

l{18} = '</listOfReactions>';
l{19} = '</model>';
l{20} = '</sbml>';

fxd = fopen([fileName,'.xml'],'w');

for i=1:13
    fprintf(fxd,'%s\n',l{i});
end
for i=1:length(comp)
    fprintf(fxd,'%s\n',comp{i});
end
for i=14:15
    fprintf(fxd,'%s\n',l{i});
end
for i=1:length(model.mets)
    fprintf(fxd,'%s\n',strcat('<',sp{i,1},'>'));
    fprintf(fxd,'%s\n',m{1});
    fprintf(fxd,'%s\n',m{2});
    fprintf(fxd,'%s\n',strcat('<p>',m{3},model.metFormulas{i,1},'</p>'));
    fprintf(fxd,'%s\n',strcat('<p>',m{4},num2str(model.metCharge(i,1)),'</p>'));
    fprintf(fxd,'%s\n',m{5});
    fprintf(fxd,'%s\n',m{6});
    fprintf(fxd,'%s\n',m{7});
end
for i=16:17
    fprintf(fxd,'%s\n',l{i});
end
for i=1:length(model.rxns)
    if model.rev(i,1)==1
        fprintf(fxd,'%s\n',strcat('<',rxn{i,1},'>'));
    else
        fprintf(fxd,'%s\n',strcat('<',rxn{i,1},' reversible="false">'));
    end
    fprintf(fxd,'%s\n',r{1});
    fprintf(fxd,'%s\n',r{2});
    fprintf(fxd,'%s\n',strcat('<p>',r{3},model.grRules{i,1},'</p>'));
    fprintf(fxd,'%s\n',strcat('<p>',r{4},model.subSystems{i,1},'</p>'));
    fprintf(fxd,'%s\n',strcat('<p>',r{5},model.rxnECNumbers{i,1},'</p>'));
    fprintf(fxd,'%s\n',strcat('<p>',r{6},model.confidenceScores{i,1},'</p>'));
    fprintf(fxd,'%s\n',strcat('<p>',r{7},model.rxnReferences{i,1},'</p>'));
    fprintf(fxd,'%s\n',r{8});
    fprintf(fxd,'%s\n',r{9});
    fprintf(fxd,'%s\n',r{10});
    if reacSense(i,1)==1
        fprintf(fxd,'%s\n',r{11});
        for j=1:length(react{i,1})
            fprintf(fxd,'%s\n',react{i,1}{j,1});
        end
        fprintf(fxd,'%s\n',r{12});
    end
    if prodSense(i,1)==1
        fprintf(fxd,'%s\n',r{13});
        for j=1:length(prod{i,1})
            fprintf(fxd,'%s\n',prod{i,1}{j,1});
        end
        fprintf(fxd,'%s\n',r{14});
    end
    for j=15:19
        fprintf(fxd,'%s\n',r{j});
    end
    fprintf(fxd,'%s\n',lb{i,1});
    fprintf(fxd,'%s\n',ub{i,1});
    fprintf(fxd,'%s\n',fv{i,1});
    fprintf(fxd,'%s\n',c{i,1});
    fprintf(fxd,'%s\n',r{20});
    fprintf(fxd,'%s\n',r{21});
    fprintf(fxd,'%s\n',r{22});
end
fprintf(fxd,'%s\n',l{18});
fprintf(fxd,'%s\n',l{19});
fprintf(fxd,'%s\n',l{20});

fclose(fxd);
