/*
 * 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;

/**
 * Converts RDFS/OWL statement.
 * @version 0.1 <1 Feb 2005>
 * @since 0.1
 */

public class OWLLiteConverter {

	protected Statement stmt;
	
	protected String SubjectNameSpace;
	protected String SubjectLocalName;
	protected String ObjectNameSpace;
	protected String ObjectLocalName;
	
	protected NameSpaceList NSL;
	private String mapping; 
	
	public OWLLiteConverter(NameSpaceList nsl, String mapping){NSL = nsl;this.mapping=mapping;}
	
	/**
	 * Converts statements with the predicate "type"
	 * to C(a)
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement with predicate "type"
	 * @param MapList the Mapping List
	 * @return ProvaModel
	 *
	 */
	
	public ProvaModel convertTYPE (ProvaModel _writer, Statement _stmt, MapperList MapList ){
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{ // not resource
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		// Object is SymmetricProperty
		if (ObjectNameSpace.equals("owl") && ObjectLocalName.equals("SymmetricProperty")){
			_writer.write(SubjectNameSpace + SubjectLocalName + "(Y,X) :- "
						  + SubjectNameSpace + SubjectLocalName + "(X,Y)." + "\n");
		// object is TransitiveProperty	
		}else if (ObjectNameSpace.equals("owl") && ObjectLocalName.equals("TransitiveProperty")){	
			_writer.write(SubjectNameSpace  + SubjectLocalName + "(X,Z) :- "
						  + SubjectNameSpace  + SubjectLocalName + "(X,Y)," + "\n"
						  + SubjectNameSpace  + SubjectLocalName + "(Y,Z)." + "\n");
			
		}else{
			// mapping element -> use mapping id
			if (MapList.isElementOfMapping(SubjectNameSpace  + SubjectLocalName)){
				_writer.write(ObjectNameSpace  + ObjectLocalName + "(" +
					"X) :- mapping(\""+	
					MapList.getHashOfElement(SubjectNameSpace  + SubjectLocalName) +
					"\",X)." + "\r\n");
			}else{ // not mapping element -> use subject as individual
				_writer.write(ObjectNameSpace  + ObjectLocalName + "(\"" +
				      SubjectNameSpace  + SubjectLocalName + "\")." +
					  "\n");			
			}
		}
		return _writer;
	}
	
	/**
	 * Converts statements with the predicate "subClassOf"
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement
	 * @return ProvaModel
	 */
	
	public ProvaModel convertSUBCLASSOF (ProvaModel _writer, Statement _stmt){
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		if (SubjectLocalName.equals(ObjectLocalName)) return _writer;

		if (mapping.equals("full")) _writer.write( // infered mode with use of fact predicate
					ObjectNameSpace + ObjectLocalName + "(X) :- fact(" + 
				    SubjectNameSpace + SubjectLocalName + "(X))." + "\n");
		else _writer.write( // non infered mode				
				ObjectNameSpace + ObjectLocalName + "(X) :- " + 
			    SubjectNameSpace + SubjectLocalName + "(X)." + "\n");
		return _writer;
	}
	
	/**
	 * Converts statements with the predicate "subPropertyOf"
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement
	 * @return ProvaModel
	 */
	
	public ProvaModel convertSUBPROPERTYOF (ProvaModel _writer, Statement _stmt) {
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		_writer.write(SubjectNameSpace + SubjectLocalName + "(X,Y) :- " 
				+ ObjectNameSpace +ObjectLocalName + "(X,Y)." + "\n");
		
		return _writer;
	}
	
	/**
	 * Converts statements with the predicate "equivalentProperty"
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement
	 * @return ProvaModel
	 */
	
	public ProvaModel convertEQUIVALENTPROPERTY (ProvaModel _writer, Statement _stmt) {
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		if (ObjectLocalName.equals(SubjectLocalName)) return _writer;
		
		if (mapping.equals("full")) {
			_writer.write(SubjectNameSpace  + SubjectLocalName + "(X,Y) :- fact(" 
				+ ObjectNameSpace  + ObjectLocalName + "(X,Y))." + "\r\n");
			_writer.write(ObjectNameSpace  + ObjectLocalName + "(X,Y) :- fact(" 
				+ SubjectNameSpace  + SubjectLocalName + "(X,Y))." + "\r\n");
		} if (mapping.equals("standard")) {
			_writer.write(SubjectNameSpace  + SubjectLocalName + "(X,Y) :- " +
					"not("+ObjectNameSpace  + ObjectLocalName+"()), "+
					"assert("+ObjectNameSpace  + ObjectLocalName+"()), "+ 
					ObjectNameSpace  + ObjectLocalName + "(X,Y).\r\n"+
					SubjectNameSpace  + SubjectLocalName + "(X,Y) :- " +
					"retractall("+ObjectNameSpace  + ObjectLocalName+"()), fail()." + "\r\n");
			
			_writer.write(ObjectNameSpace  + ObjectLocalName + "(X,Y) :- " 
					+ SubjectNameSpace  + SubjectLocalName + "(X,Y)." + "\r\n");
		}else {
			_writer.write(SubjectNameSpace  + SubjectLocalName + "(X,Y) :- " 
					+ ObjectNameSpace  + ObjectLocalName + "(X,Y)." + "\r\n");
			_writer.write(ObjectNameSpace  + ObjectLocalName + "(X,Y) :- " 
					+ SubjectNameSpace  + SubjectLocalName + "(X,Y)." + "\r\n");
		}
		return _writer;
	}

	/**
	 * Converts statements with the predicate "domain"
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement
	 * @return ProvaModel
	 */
	
	public ProvaModel convertDOMAIN (ProvaModel _writer, Statement _stmt) {
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		_writer.write(ObjectNameSpace + ObjectLocalName + "(X) :- " +
				SubjectNameSpace +  SubjectLocalName + "(X,Y)." + "\n");
		
		return _writer;
	}
	
	/**
	 * Converts statements with the predicate "range"
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement
	 * @return ProvaModel
	 */
	
	public ProvaModel convertRANGE (ProvaModel _writer, Statement _stmt) {
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			if (ObjectNameSpace.equals("xmlns_")) return _writer;
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		_writer.write(ObjectNameSpace + ObjectLocalName + "(Y) :- " +
				SubjectNameSpace +  SubjectLocalName + "(X,Y)." + "\n");
		
		return _writer;
	}

	/**
	 * Converts statements with the predicate "sameAs"
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement
	 * @param MapList the List which contains the mapping of the individuals
	 * @return ProvaModel
	 */
	
	public ProvaModel convertSAMEAS (ProvaModel _writer, Statement _stmt, MapperList MapList) {
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		if (ObjectLocalName.equals(SubjectLocalName)) return _writer;
		
		if (mapping.equals("full")) {
			if (!(MapList.isElementOfMapping(SubjectNameSpace + SubjectLocalName)
				&& MapList.isElementOfMapping(ObjectNameSpace + ObjectLocalName))){
				_writer.write(ObjectNameSpace + ObjectLocalName + "(X) :- fact("
					     + SubjectNameSpace + SubjectLocalName + "(X))." + "\r\n");
				_writer.write(SubjectNameSpace  + SubjectLocalName + "(X) :- fact("
				     + ObjectNameSpace + ObjectLocalName + "(X))." + "\r\n");
				return _writer;
			} else return _writer;
		}  else if (mapping.equals("standard")) {
			if (!(MapList.isElementOfMapping(SubjectNameSpace + SubjectLocalName)
					&& MapList.isElementOfMapping(ObjectNameSpace + ObjectLocalName))){
			_writer.write(ObjectNameSpace + ObjectLocalName + "(X) :- "+
					"not("+ObjectNameSpace + ObjectLocalName +"()), "+
					"assert("+ObjectNameSpace + ObjectLocalName +"()), "+
				    SubjectNameSpace + SubjectLocalName + "(X).\r\n"+
				    ObjectNameSpace + ObjectLocalName + "(X) :- retractall("+ObjectNameSpace + ObjectLocalName +"()), fail()." + "\r\n");
			_writer.write(SubjectNameSpace  + SubjectLocalName + "(X) :- "
			     + ObjectNameSpace + ObjectLocalName + "(X)." + "\r\n");
			return _writer;} else return _writer;
		} else { // not infered
			_writer.write(ObjectNameSpace + ObjectLocalName + "(X) :- "
				     + SubjectNameSpace + SubjectLocalName + "(X)." + "\n");
			_writer.write(SubjectNameSpace  + SubjectLocalName + "(X) :- "
			     + ObjectNameSpace + ObjectLocalName + "(X)." + "\r\n");
			return _writer;
		}
	}
	
	/**
	 * Converts statements with the predicate "inverseOf"
	 * 
	 * @param _writer the ProvaModel
	 * @param _stmt the JENA Statement
	 * @return ProvaModel
	 */
	
	public ProvaModel convertINVERSEOF (ProvaModel _writer, Statement _stmt) {
		stmt = _stmt;
		
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
			ObjectLocalName = new String(resImpl.getLocalName());
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
		}
		
		_writer.write(SubjectNameSpace + SubjectLocalName + "(Y,X) :- " +
				ObjectNameSpace +  ObjectLocalName + "(X,Y)." + "\n");
		
		return _writer;
	}
	
}
