/*
 * 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 statement according to their predicat. This class is responsible for statements
 * with reification keys.
 * @version 0.1 <1 Feb 2005>
 * @since 0.1
 */
public class OWLAnonConverter {

	protected Statement stmt;
	
	protected String Subject;
	protected String SubjectNameSpace;
	protected String SubjectLocalName;
	protected String Object;
	protected String ObjectNameSpace;
	protected String ObjectLocalName;
	
	protected NameSpaceList NSL;
	
	private String mapping;
	
	public OWLAnonConverter(NameSpaceList nsl, String mapping){NSL=nsl;this.mapping=mapping;}
	
	/**
	 * Converts statements with the predicate "type"
	 * 
	 * @param _writer ProvaModel
	 * @param _stmt the JENA Statement with predicate "type"
	 * @param MapList the Mapping List
	 * @param isSubjectAnon identifies the Subject as reification key
	 * @param isObjectAnon identifies the Object as reification key
	 * @return ProvaModel
	 *
	 */
	
	public ProvaModel convertTYPE (ProvaModel _writer, Statement _stmt, MapperList MapList,
			   boolean isSubjectAnon,
			   boolean isObjectAnon ){
		stmt = _stmt;
		
		if (isSubjectAnon && isObjectAnon){
			Subject = "_anon" + Integer.toString(
					MapList.getHashOfElement(
					stmt.getSubject().getId().toString()));
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			Object = "_anon" + Integer.toString(
						MapList.getHashOfElement(
					    resImpl.getId().toString()));
		}else if (isSubjectAnon && (!isObjectAnon)){
			Subject = "_anon" + Integer.toString(
					MapList.getHashOfElement(
					stmt.getSubject().getId().toString()));
			if (stmt.getObject() instanceof ResourceImpl ){
				ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
				ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
				ObjectLocalName = new String(resImpl.getLocalName());
				Object = ObjectNameSpace + ObjectLocalName;
			}else{
				ObjectNameSpace = new String("error:class_not_");
				ObjectLocalName = new String("a_valid_resource");
				Object = ObjectNameSpace + ObjectLocalName;
			}
		}else{
			SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
			SubjectLocalName = new String(stmt.getSubject().getLocalName());
			Subject = SubjectNameSpace + SubjectLocalName;
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			Object = "_anon" + Integer.toString(
						MapList.getHashOfElement(
					    resImpl.getId().toString()));
		}
		
		if (Object.equals("owl_SymmetricProperty")){
			_writer.write(Subject + "(Y,X) :- "
						  + Subject + "(X,Y)." + "\n");
			
		}else if (Object.equals("owl_TransitiveProperty")){	
			_writer.write(Subject + "(X,Z) :- "
						  + Subject + "(X,Y)," + "\n"
						  + Subject + "(Y,Z)." + "\n");
			
		}else{
			// insert mapping ID
			if (MapList.isElementOfMapping(Subject)){
				_writer.write(Object + "(X) :- mapping(\"" +
					MapList.getHashOfElement(Subject) +
					"\", X)." + "\r\n");
			}else{ // use individual
				_writer.write(Object + "(\"" +
				      Subject + "\")." +
					  "\r\n");			
			}
		}
		
		return _writer;
	}
	
	/**
	 * Converts statements with the predicate "subClassOf"
	 * 
	 * @param _writer ProvaModel
	 * @param _stmt the JENA Statement
	 * @param MapList the Mapping List
	 * @param isSubjectAnon identifies the Subject as reification key
	 * @param isObjectAnon identifies the Object as reification key
	 * @return ProvaModel
	 */
	
	public ProvaModel convertSUBCLASSOF (ProvaModel _writer, Statement _stmt, MapperList MapList, 
			   boolean isSubjectAnon,
			   boolean isObjectAnon){
		stmt = _stmt;
		
		if (isSubjectAnon && isObjectAnon){
			Subject = "_anon" + Integer.toString(
					MapList.getHashOfElement(
					stmt.getSubject().getId().toString()));
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			Object = "_anon" + Integer.toString(
						MapList.getHashOfElement(
					    resImpl.getId().toString()));
		}else if (isSubjectAnon && (!isObjectAnon)){
			Subject = "_anon" + Integer.toString(
					MapList.getHashOfElement(
					stmt.getSubject().getId().toString()));
			if (stmt.getObject() instanceof ResourceImpl ){
				ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
				ObjectNameSpace = new String(NSL.getAbbreviation(resImpl.getNameSpace()));
				ObjectLocalName = new String(resImpl.getLocalName());
				Object = ObjectNameSpace + ObjectLocalName;
			}else{
				ObjectNameSpace = new String("error:class_not_");
				ObjectLocalName = new String("a_valid_resource");
				Object = ObjectNameSpace + ObjectLocalName;
			}
		}else{
			SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
			SubjectLocalName = new String(stmt.getSubject().getLocalName());
			Subject = SubjectNameSpace + SubjectLocalName;
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			Object = "_anon" + Integer.toString(
						MapList.getHashOfElement(
					    resImpl.getId().toString()));
		}
			
		if (mapping.equals("full")) _writer.write(
					Object + "(X) :- fact(" + 
				    Subject + "(X))." + "\r\n");
		else  _writer.write(
				Object + "(X) :- " + 
			    Subject + "(X)." + "\r\n");
		return _writer;
	}
	

	/**
	 * Converts statements with the predicate "domain"
	 * 
	 * @param _writer ProvaModel
	 * @param _stmt the JENA Statement
	 * @param MapList the Mapping List
	 * @param isSubjectAnon identifies the Subject as reification key
	 * @param isObjectAnon identifies the Object as reification key
	 * @return ProvaModel
	 */
	public ProvaModel convertDOMAIN (ProvaModel _writer, Statement _stmt, MapperList MapList,
			   boolean isSubjectAnon,
			   boolean isObjectAnon) {
		stmt = _stmt;
		/*
		 * Nur Object kann ein Anon sein! 
		 * Subject bezeichnet die Property
		 */
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		Subject = SubjectNameSpace + SubjectLocalName;
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			Object = "_anon" + Integer.toString( // anon
					MapList.getHashOfElement(
				    resImpl.getId().toString()));
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
			Object = ObjectNameSpace + ObjectLocalName;
		}
		
		_writer.write(Object + "(X) :- " +
					  Subject + "(X,Y)." + "\r\n");
		
		return _writer;
	}
	
	/**
	 * Converts statements with the predicate "range"
	 * 
	 * @param _writer ProvaModel
	 * @param _stmt the JENA Statement
	 * @param MapList the Mapping List
	 * @param isSubjectAnon identifies the Subject as reification key
	 * @param isObjectAnon identifies the Object as reification key
	 * @return ProvaModel
	 */
	
	public ProvaModel convertRANGE (ProvaModel _writer, Statement _stmt, MapperList MapList,
			   boolean isSubjectAnon,
			   boolean isObjectAnon) {
		stmt = _stmt;
		/*
		 * Nur Object kann ein Anon sein! 
		 * Subject bezeichnet die Property
		 */
		SubjectNameSpace = new String(NSL.getAbbreviation(stmt.getSubject().getNameSpace()));
		SubjectLocalName = new String(stmt.getSubject().getLocalName());
		Subject = SubjectNameSpace + SubjectLocalName;
		
		if (stmt.getObject() instanceof ResourceImpl ){
			ResourceImpl resImpl = (ResourceImpl) stmt.getObject();
			Object = "_anon" + Integer.toString( // anon
					MapList.getHashOfElement(
				    resImpl.getId().toString()));
		}else{
			ObjectNameSpace = new String("error:class_not_");
			ObjectLocalName = new String("a_valid_resource");
			Object = ObjectNameSpace + ObjectLocalName;
		}
		
		_writer.write(Object + "(Y) :- " +
					  Subject + "(X,Y)." + "\n");
		
		return _writer;
	}

	
}
