package uk.ac.ed.inf.Metabolic.sbmlexport;

import java.util.List;

import org.sbml.libsbml.KineticLaw;
import org.sbml.libsbml.Model;
import org.sbml.libsbml.ModifierSpeciesReference;
import org.sbml.libsbml.Reaction;
import org.sbml.libsbml.SBase;
import org.sbml.libsbml.SpeciesReference;

import uk.ac.ed.inf.Metabolic.ndomAPI.IModel;
import uk.ac.ed.inf.Metabolic.ndomAPI.IReaction;
import uk.ac.ed.inf.Metabolic.ndomAPI.IRelation;

class SBMLReactionFactory implements IReactionBuilder {

	public void buildReactions(Model sbmlModel, IModel model) {
		for (IReaction reaction: model.getReactionList()){
			
			// reactions msut at least one substrate or product
			if(reactionIsEmpty(reaction)){
				continue;
			}
			Reaction sbmlReaction = sbmlModel.createReaction();
			sbmlReaction.setId(reaction.getId());
			sbmlReaction.setName(reaction.getASCIIName());
			sbmlReaction.setReversible(reaction.isReversible());
			
			setUpKineticLaw(sbmlReaction, reaction);
			
			
			AnnotationBuilder builder = new ReactionAnnotationBuilder(reaction);
			addAnnotationAndNotes(sbmlReaction, builder);
			List<IRelation> substrates = reaction.getSubstrateList();
			for (IRelation substrate: substrates) {
			   sbmlReaction.addReactant(createSpeciesReference(substrate));
			}
			
			List<IRelation> products = reaction.getProductList();
			for (IRelation product: products) {
			   sbmlReaction.addProduct(createSpeciesReference(product));
			}
			
			List<IRelation> modifiers = reaction.getCatalystList();
			modifiers.addAll(reaction.getInhibitorList());
			modifiers.addAll(reaction.getActovatorList());
			for (IRelation modifier: modifiers) {
				ModifierSpeciesReference msr = new ModifierSpeciesReference(modifier.getId());
			    sbmlReaction.addModifier(msr);
			}
		}

	}

	private SpeciesReference createSpeciesReference(IRelation substrate) {
		SpeciesReference sr = new SpeciesReference(substrate.getId(), substrate.getStoichiometry());
		StringBuffer sb = new StringBuffer();
		 sb.append("<p xmlns='http://www.w3.org/1999/xhtml'>");
		 sb.append(substrate.getRole());
		 sb.append("</p>");
		sr.appendNotes(sb.toString());
		return sr;
	}

	private void setUpKineticLaw(Reaction sbmlReaction, IReaction reaction) {
		KineticLaw law = sbmlReaction.createKineticLaw();
		StringBuffer sb = new StringBuffer();
		 sb.append("<p xmlns='http://www.w3.org/1999/xhtml'>");
		 sb.append(reaction.getKineticLaw());
		 sb.append("</p>");
		law.appendNotes(sb.toString());
		
	}

	private boolean reactionIsEmpty(IReaction reaction) {
		return reaction.getSubstrateList().isEmpty() && reaction.getProductList().isEmpty();
	}
	
	private void addAnnotationAndNotes(SBase sbmlObject, AnnotationBuilder builder) {
		String annotation = builder.buildAnnotation();
		sbmlObject.appendAnnotation(annotation);
		String notes = builder.buildNotes();
		sbmlObject.appendNotes(notes);
	}

}

@@ -33,24 +33,52 @@
 bmlexport;%0A%0A
+import java.util.ArrayList;%0A
 import java.
@@ -1458,36 +1458,32 @@
 product));%0A%09%09%09%7D%0A
-%09%09%09%0A
 %09%09%09List%3CIRelatio
@@ -1488,21 +1488,56 @@
 ion%3E
- modifiers = 
+all = new ArrayList%3CIRelation%3E();%0A%09%09%09all.addAll(
 reac
@@ -1558,30 +1558,25 @@
 stList()
+)
 ;%0A%09%09%09
-modifiers
+all
 .addAll(
@@ -1608,25 +1608,19 @@
 ());%0A%09%09%09
-modifiers
+all
 .addAll(
@@ -1681,17 +1681,11 @@
 er: 
-modifiers
+all
 ) %7B%0A
@@ -1723,20 +1723,22 @@
 r = 
-new 
+create
 Modifier
 Spec
@@ -1725,39 +1725,32 @@
 = createModifier
-Species
 Reference(modifi
@@ -1751,24 +1751,16 @@
 modifier
-.getId()
 );%0A%09%09%09  
@@ -1815,16 +1815,24 @@
 private 
+Modifier
 SpeciesR
@@ -1842,31 +1842,32 @@
 rence create
-Species
+Modifier
 Reference(IR
@@ -1878,23 +1878,30 @@
 ion 
-substrate) %7B%0A%09%09
+modifier) %7B%0A%09%09Modifier
 Spec
@@ -1913,16 +1913,17 @@
 ference 
+m
 sr = new
@@ -1923,16 +1923,24 @@
 r = new 
+Modifier
 SpeciesR
@@ -1952,57 +1952,145 @@
 nce(
-substrate.getId(), substrate.getStoichiometry());
+modifier.getId());%0A%09%09%0A%09%09addRoleToNotes(msr, modifier.getRole());%0A%09%09return msr;%0A%09%7D%0A%0A%09private void addRoleToNotes(SBase ref, String role) %7B
 %0A%09%09S
@@ -2172,32 +2172,38 @@
 org/1999/xhtml'%3E
+ Role:
 %22);%0A%09%09 sb.append
@@ -2207,27 +2207,12 @@
 end(
-substrate.getR
+r
 ole
-()
 );%0A%09
@@ -2234,18 +2234,20 @@
 p%3E%22);%0A%09%09
-sr
+ ref
 .appendN
@@ -2263,24 +2263,241 @@
 oString());%0A
+%09%09%0A%09%7D%0A%0A%09private SpeciesReference createSpeciesReference(IRelation substrate) %7B%0A%09%09SpeciesReference sr = new SpeciesReference(substrate.getId(), substrate.getStoichiometry());%0A%09%09addRoleToNotes(sr, substrate.getRole());%0A
 %09%09return sr;

handle addAll modifiers