package fr.inrialpes.exmo.ontosim.entity.model;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import fr.inrialpes.exmo.ontowrap.HeavyLoadedOntology;

public class HLPropertyImpl<E> extends HLEntityImpl<E> implements HLProperty<E>{

    protected HLPropertyImpl(HeavyLoadedOntology<E> ont, E e) {
	super(ont, e);
	// TODO Auto-generated constructor stub
    }
    private List<Reference<Set<HLProperty<E>>>> subproperties;
    private List<Reference<Set<HLProperty<E>>>> superproperties;
    private List<Reference<Set<HLClass<E>>>> ranges;
    private List<Reference<Set<HLClass<E>>>> domains;
    
    /* Property methods */
    @SuppressWarnings("unchecked")
    public Set<HLProperty<E>> getSubProperties(int local, int asserted, int named ) {
	if (subproperties==null) subproperties=new Vector<Reference<Set<HLProperty<E>>>>();
	int idx = getIdx(local,asserted,named);
	while (subproperties.size()<=idx) subproperties.add(null);
	if (subproperties.get(idx)==null  || subproperties.get(idx).get()==null) 
	    subproperties.set(idx, new SoftReference<Set<HLProperty<E>>>((Set<HLProperty<E>>)fact.getFrom((Set<E>)onto.getSubProperties(getObject(), local, asserted, named))));
	return subproperties.get(idx).get();
    }
    
    @SuppressWarnings("unchecked")
    public Set<HLProperty<E>> getSuperProperties(int local, int asserted, int named ) {
	if (superproperties==null) superproperties=new Vector<Reference<Set<HLProperty<E>>>>();
	int idx = getIdx(local,asserted,named);
	while (superproperties.size()<=idx) superproperties.add(null);
	if (superproperties.get(idx)==null  || superproperties.get(idx).get()==null) 
	    superproperties.set(idx, new SoftReference<Set<HLProperty<E>>>((Set<HLProperty<E>>)fact.getFrom((Set<E>)onto.getSuperProperties(getObject(), local, asserted, named))));
	return superproperties.get(idx).get();
    }
    
    @SuppressWarnings("unchecked")
    public Set<HLClass<E>> getRange(int asserted) {
	if (ranges==null) ranges=new Vector<Reference<Set<HLClass<E>>>>();
	int idx = getIdx(0,asserted,0);
	while (ranges.size()<=idx) ranges.add(null);
	if (ranges.get(idx)==null  || ranges.get(idx).get()==null) 
	    ranges.set(idx, new SoftReference<Set<HLClass<E>>>((Set<HLClass<E>>)fact.getFrom((Set<E>)onto.getRange(getObject(), asserted))));
	return ranges.get(idx).get();
    }
    
    @SuppressWarnings("unchecked")
    public Set<HLClass<E>> getDomain(int asserted) {
	if (domains==null) domains=new Vector<Reference<Set<HLClass<E>>>>();
	int idx = getIdx(0,asserted,0);
	while (domains.size()<=idx) domains.add(null);
	if (domains.get(idx)==null  || domains.get(idx).get()==null) 
	    domains.set(idx, new SoftReference<Set<HLClass<E>>>((Set<HLClass<E>>)fact.getFrom((Set<E>)onto.getDomain(getObject(), asserted))));
	return domains.get(idx).get();
    }
}
