package de.uka.ipd.consensus.impl;

import de.uka.ipd.consensus.foundation.ontology.OntologyManagerException;
import de.uka.ipd.consensus.foundation.rights.DynamicRightsManager;
import de.uka.ipd.consensus.foundation.rights.DynamicRightsManagerException;
import de.uka.ipd.consensus.foundation.schema.Concept;
import de.uka.ipd.consensus.foundation.schema.User;
import de.uka.ipd.consensus.foundation.schema.Version;

/**
 * 
 * TODO
 * @author Thomas Much
 * @version 2006-06-14
 */
public abstract class TM4JTopicWrapper extends TM4JObjectWrapper implements Concept {
	
	private User   creator = null;
	private String name    = null;

	
	protected TM4JTopicWrapper(OntologyManagerImpl omi, org.tm4j.topicmap.Topic tmTopic) {
		super(omi,tmTopic);
	}


	protected org.tm4j.topicmap.Topic getWrappedTopic() {
		return (org.tm4j.topicmap.Topic)this.getWrappedObject();
	}


	public String getId() {
		return this.getObjectId();
	}
	
	
	public User getCreator() {
		if (this.creator == null) {
			this.creator = this.getOntologyManager().getCreator( this.getWrappedTopic() );
		}
		return this.creator;
	}
	
	
	/**
	 * must not return null
	 */
	public String getName() {
		if (this.name == null) {
			this.name = this.getOntologyManager().getTopicName( this.getWrappedTopic() );
		}
		return this.name;
	}


	public void setName(User setter, String name) throws OntologyManagerException,DynamicRightsManagerException {
		try {
			String oldName = this.getName();
			this.getOntologyManager().setTopicName( this.getWrappedTopic(), name );
			this.name = name;
			this.incVersion();
			this.getOntologyManager().fireConceptNameChanged( this, setter, oldName );
		}
		catch (Exception e) {
			throw new OntologyManagerException( e );
		}
	}


	protected org.tm4j.topicmap.Occurrence getOccurrence(org.tm4j.topicmap.Topic tmType) {
		return getOccurrence( this.getWrappedTopic(), tmType );
	}

	
	/**
	 * must not return null
	 */
	public String getComment() {
		org.tm4j.topicmap.Occurrence occ = this.getOccurrence( this.getOntologyManager().getCommentTopicType() );
		if (occ != null) {
			return occ.getData();
		}
		else {
			return "";
		}
	}
	
	
	public void setComment(User setter, String comment) throws OntologyManagerException,DynamicRightsManagerException {
		DynamicRightsManager drm = this.getOntologyManager().getDynamicRightsManager();
		if (drm != null) {
			drm.checkChangeConceptComment( setter, this );
		}
		
		if (comment == null) {
			comment ="";
		}
		
		try {
			String oldComment;
			org.tm4j.topicmap.Occurrence occ = this.getOccurrence( this.getOntologyManager().getCommentTopicType() );
			if (occ != null) {
				oldComment = occ.getData();
				if (comment.equals(oldComment)) return;
				occ.setData( comment );
			}
			else {
				if (comment.length() == 0) return;
				oldComment = "";
				this.getWrappedTopic().createOccurrence( null, null, this.getOntologyManager().getCommentTopicType(), comment, EMPTY_SCOPE );
			}
			this.incVersion();
			this.getOntologyManager().fireConceptCommentChanged( this, setter, oldComment );
		}
		catch (Exception e) {
			throw new OntologyManagerException( "Error setting concept comment: " + e );
		}
	}


	protected Version incVersion() {
		org.tm4j.topicmap.Occurrence occ = this.getOccurrence( this.getOntologyManager().getVersionTopicType() );
		if (occ == null) {
			Version neu   = new VersionImpl( this );
			String  msstr = String.valueOf( neu.getDate().getTime() );
			try {
				this.getWrappedTopic().createOccurrence( null, null, this.getOntologyManager().getVersionTopicType(), msstr, EMPTY_SCOPE );
			}
			catch (Exception e) {
				this.getLoggingManager().error("Error creating concept version: " + e);
			}
			return neu;
		}
		else {
			long ms = -1L;
			String msstr = occ.getData();
			if ((msstr != null) && (msstr.length() > 0)) {
				try {
					ms = Long.parseLong( msstr );
				}
				catch (NumberFormatException e) { }
			}
			VersionImpl ver;
			if (ms == -1) {
				ver = new VersionImpl( this );
			}
			else {
				ver = new VersionImpl( this, ms );
				ver.inc();
			}
			msstr = String.valueOf( ver.getDate().getTime() );
			try {
				occ.setData( msstr );
			}
			catch (Exception e) {
				this.getLoggingManager().error("Error incrementing concept version: " + e);
			}
			return ver;
		}
	}


	public Version getVersion() {
		org.tm4j.topicmap.Occurrence occ = this.getOccurrence( this.getOntologyManager().getVersionTopicType() );
		if (occ != null) {
			String msstr = occ.getData();
			if ((msstr != null) && (msstr.length() > 0)) {
				try {
					long ms = Long.parseLong( msstr );
					return new VersionImpl( this, ms );
				}
				catch (NumberFormatException e) { }
			}
		}
		return this.incVersion();
	}
	
	
	public int compareTo(Object other) {
		return this.getName().toLowerCase().compareTo( ((Concept)other).getName().toLowerCase() );
	}

}
