package com.libreecm.db.jpa.properties;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.hibernate.annotations.GenericGenerator;

import com.libreecm.commonAPI.model.objects.ExtensionsData;
import com.libreecm.commonAPI.model.objects.properties.PropertyData;

@Entity
public class Properties extends ExtensionsData {


	@Id
	@GeneratedValue(generator="hilo-gen")
	@GenericGenerator(name="hilo-gen", strategy="hilo")
	private Integer id;

	@Transient
    private static final long serialVersionUID = 1L;

    @OneToMany
    private final List<PropertyData<?>> propertyList = new ArrayList<PropertyData<?>>();
    private final Map<String, PropertyData<?>> properties = new LinkedHashMap<String, PropertyData<?>>();

    public String getId(){
    	if (this.id==null)
    		return null;
    	return this.id.toString();
    }
    
    public void setId(String id){
    	this.id=Integer.parseInt(id);
    }
    
    /**
     * Constructor.
     */
    public Properties() {
    }

    /**
     * Constructor.
     * 
     * @param properties
     *            initial collection of properties
     */
    public Properties(Collection<PropertyData<?>> properties) {
        addProperties(properties);
    }

    /**
     * Shallow copy constructor.
     * 
     * Creates a new collection of properties but references the original
     * property and extension objects.
     */
    public Properties(Properties properties) {
        if (properties == null) {
            throw new IllegalArgumentException("Properties not set!");
        }

        addProperties(properties.getPropertyList());
        setExtensions(properties.getExtensions());
    }

    public Map<String, PropertyData<?>> getProperties() {
        return Collections.unmodifiableMap(properties);
    }

    public List<PropertyData<?>> getPropertyList() {
        return Collections.unmodifiableList(propertyList);
    }

    protected void addProperties(Collection<PropertyData<?>> properties) {
        if (properties != null) {
            for (PropertyData<?> prop : properties) {
                addProperty(prop);
            }
        }
    }

    public void addProperty(PropertyData<?> property) {
        if (property == null) {
            return;
        }

        propertyList.add(property);
        properties.put(property.getId(), property);
    }

    public void replaceProperty(PropertyData<?> property) {
        if (property == null || property.getId() == null) {
            return;
        }

        removeProperty(property.getId());

        propertyList.add(property);
        properties.put(property.getId(), property);
    }

    public void removeProperty(String id) {
        if (id == null) {
            return;
        }

        Iterator<PropertyData<?>> iterator = propertyList.iterator();
        while (iterator.hasNext()) {
            PropertyData<?> property = iterator.next();
            if (id.equals(property.getId())) {
                iterator.remove();
                break;
            }
        }

        properties.remove(id);
    }

    @Override
    public String toString() {
        return "Properties Data [properties=" + propertyList + "]" + super.toString();
    }

}
