/*
 * Copyright (C) 1999-2006 <a href="mailto:paschke@in.tum.de">Adrian Paschke</a>
 * 
 * The OWL2Prova library is part of the Rule Based Service Level Agreement (RBSLA)
 * framework, available at 
 * <a href=" http://ibis.in.tum.de/staff/paschke/rbsla/index.htm">RBSLA</a>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package rbsla.owl.converter.dlp;

import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.impl.ResourceImpl;
import rbsla.owl.NameSpaceList;
import rbsla.owl.ProvaModel;

/**
 * Checks the predicates of the JENA statements and calls the corresponding translation method
 * @version 0.1 <1 Feb 2005>
 * @since 0.1
 */
public class OwlPredicateChooser {

	protected String PredicateNameSpace;
	protected String PredicateLocalName;
	protected NameSpaceList NSL; // namespace list
	protected Statement stmt;
	
	protected OWLLiteConverter olc; // internal converter for rdfs/owl predicates
	protected OWLAnonConverter oac; // internal converter for anons
	protected OWLStandardConverter osc; // internal converter for user defined predicates
	
	protected MapperList MapList;
	private String mapping;
	

	/**Constructor
	 * @param _MapList List which contains the mapping of Individuals to their identifier
	 */
	public OwlPredicateChooser(MapperList _MapList, NameSpaceList nsl, String mapping){
		MapList = _MapList;
		NSL = nsl;
		this.mapping=mapping;
		if (mapping.equals("lite")) {
			olc = new OWLLiteConverter(NSL,"lite");
			oac = new OWLAnonConverter(NSL,"lite");
		}
		else if (mapping.equals("standard")) {
			olc = new OWLLiteConverter(NSL,"standard");
			oac = new OWLAnonConverter(NSL,"standard");
		} else {
			olc = new OWLLiteConverter(NSL,"full"); // inferred model --> use full mapping
			oac = new OWLAnonConverter(NSL,"full");
		}
		
		osc = new OWLStandardConverter(NSL);
	}	
		
	/** the appearence of an anon element a special choice has to be made.
	 * 
	 * @param _stmt the JENA statement
	 * @param _writer ProvaModel
	 * @return ProvaModel
	 */
	public ProvaModel convertStatement (Statement _stmt, ProvaModel _writer){		
		Statement tmpStmt = _stmt;		
		boolean isObjectRes;
		if (tmpStmt.getObject() instanceof ResourceImpl){
			isObjectRes = true; // is resource
		}else{
			isObjectRes = false; // is literal
		}
		
		if (tmpStmt.getSubject().isAnon()){ // subject is anon
			if (isObjectRes){ // object is resource
				ResourceImpl res = (ResourceImpl) tmpStmt.getObject();
				if (res.isAnon()){ // object is anone, too
					return this.chooseAnonRule(_stmt, _writer, true, true); // use anon converter
				}
			}
			return this.chooseAnonRule(_stmt, _writer, true, false); // only subject is anon
		} 
		
		if (isObjectRes){ // subject is not anon 
			ResourceImpl res = (ResourceImpl) tmpStmt.getObject();
			if (res.isAnon()){ // object is anon
				return this.chooseAnonRule(_stmt, _writer, false,true); // use anon converter
			}
		}
		
		return this.chooseRule(_stmt, _writer); // use standard or lite converter
	}
	
	/**
	 * checks the predicate of the statement and calls the corresponing translation mehtod
	 * 
	 * @param _stmt the JENA statement
	 * @param _writer ProvaModel
	 * @return ProvaModel
	 */
	public ProvaModel chooseRule (Statement _stmt, ProvaModel _writer){
		
		stmt = _stmt;
		
		PredicateNameSpace = stmt.getPredicate().getNameSpace();
		PredicateLocalName = stmt.getPredicate().getLocalName();

		if (PredicateNameSpace.equals(NSL.getNameSpace("rdf"))
			&& PredicateLocalName.equals("type")){ // type predicate
			
			_writer = olc.convertTYPE(_writer, stmt, MapList); // use lite converter
			
		}else if(PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
			&& PredicateLocalName.equals("subClassOf")){ // subClassOf predicate
			
			_writer = olc.convertSUBCLASSOF(_writer, stmt); // use lite converter
			
		}else if (PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("equivalentProperty")){ // equivalentProperty
			
			_writer = olc.convertEQUIVALENTPROPERTY(_writer, stmt); // use lite converter
			
		}else if (PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
			&& PredicateLocalName.equals("subPropertyOf")){ // subPropertyOf
			
			_writer = olc.convertSUBPROPERTYOF(_writer, stmt); // use lite converter
			
		}else if (PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
				&& PredicateLocalName.equals("domain")){
			
			_writer = olc.convertDOMAIN(_writer, stmt);
			
		}else if (PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
				&& PredicateLocalName.equals("range")){
			
			_writer = olc.convertRANGE(_writer, stmt);
			
		} else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("sameAs")){
			
			//TODO SAMEAS for classes and individuals
			if (!mapping.equals("full")) _writer = olc.convertSAMEAS(_writer, stmt,MapList);
			
			
		} else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("sameIndividualAs")){
			
			//TODO SAMEAS for classes and individuals
			if (!mapping.equals("full")) _writer = olc.convertSAMEAS(_writer, stmt,MapList);
		
		} else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("equivalentClass")){
			
			//TODO SAMEAS for classes and individuals
			if (!mapping.equals("full")) _writer = olc.convertSAMEAS(_writer, stmt,MapList);
			
			
		} else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("inverseOf")){
			
			_writer = olc.convertINVERSEOF(_writer, stmt);
			
		}else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("differentFrom")){
			/**
			 * the differentForm statements are analysed and converted in the mapping process
			 */
		
		}else{ // convert user defined properties			
			_writer = osc.writeAllStatements(_writer, stmt, MapList); // use standard converter			
		}
		
		return _writer;
	}
	
	/**
	 * checks the predicate of the statement and calls the corresponing translation mehtod
	 * in the case that one of the elements (subject or object) are a reification key
	 * 
	 * @param _stmt the JENA Statement
	 * @param _writer ProvaModel
	 * @param anonSubject indicates if the Subject is a reification key
	 * @param anonObject indicates if the Object is a reification key
	 * @return ProvaModel
	 */
	public ProvaModel chooseAnonRule (Statement _stmt, ProvaModel _writer, boolean anonSubject, boolean anonObject){
		stmt = _stmt;
		
		PredicateNameSpace = stmt.getPredicate().getNameSpace();
		PredicateLocalName = stmt.getPredicate().getLocalName();
		
		if (PredicateNameSpace.equals(NSL.getNameSpace("rdf"))
			&& PredicateLocalName.equals("type")){
			
			_writer = oac.convertTYPE(_writer, stmt, MapList, anonSubject, anonObject);
			
		}else if(PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
			&& PredicateLocalName.equals("subClassOf")){
			
			_writer = oac.convertSUBCLASSOF(_writer, stmt, MapList, anonSubject, anonObject);
			
		}else if (PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
			&& PredicateLocalName.equals("subPropertyOf")){
			
			//_writer = oac.convertSUBPROPERTYOF(_writer, stmt, MapList, anonSubject, anonObject);
			
		}else if (PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
				&& PredicateLocalName.equals("domain")){
			
			_writer = oac.convertDOMAIN(_writer, stmt, MapList, anonSubject, anonObject);
			
		}else if (PredicateNameSpace.equals(NSL.getNameSpace("rdfs"))
				&& PredicateLocalName.equals("range")){
			
			_writer = oac.convertRANGE(_writer, stmt, MapList, anonSubject, anonObject);
			
		}else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("sameAs")){
			
			/**
			 * the sameAs statements are analysed and converted in the mapping process
			 */
			
		}else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("inverseOf")){
			
			//_writer = oac.convertINVERSEOF(_writer, stmt, MapList, anonSubject, anonObject);
			
		}else if(PredicateNameSpace.equals(NSL.getNameSpace("owl"))
				&& PredicateLocalName.equals("differentFrom")){
			/**
			 * the differentForm statements are analysed and converted in the mapping process
			 */
		
		}else{
			_writer = osc.writeAllStatements(_writer, stmt, MapList, anonSubject, anonObject); // standard converter
		}
		
		return _writer;
	}
	
}
