/*
 * Image.java
 * Last modified by: $Author: amarkhel $
 * $Revision: 11437 $	$Date: 2008-11-28 18:00:59 +0200 $
 */
package org.richfaces.realworld.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;

import org.hibernate.validator.Length;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

/**
 * Class for representing Image Entity
 *  EJB3 Entity Bean
 * 
 * @author Andrey Markhel
 */
@Entity
@Name("image")
@Scope(ScopeType.PAGE)
@Table(name = "Images")
public class Image implements Serializable {

    private static final long serialVersionUID = -7042878411608396483L;

    @Id
    @GeneratedValue
    @Column(name = "IMAGE_ID")
    private Long id = null;
    
    @Version
    @Column(name = "OBJ_VERSION")
    private int version = 0;

    @Column(length = 255, nullable = false)
    @NotNull
	@NotEmpty
    @Length(min=3)
    private String name;

    @Column(length = 1024, nullable = false)
    @NotNull
	@NotEmpty
    @Length(min=3)
    private String path;
    
    @OneToOne
    @JoinColumn(name="RANK_ID")
    private Rank rank; 
    
/*    @org.hibernate.annotations.CollectionOfElements(targetElement = java.lang.String.class)
	@JoinTable(name = "IMAGE_TAGS", joinColumns = @JoinColumn(name = "IMAGE_ID"))
	@Column(name = "TAG", nullable = false)
	private Set<String> tags = new HashSet<String>();*/
    
    @Column(length = 1024)
    @NotNull
	@NotEmpty
    @Length(min=3)
    private String description;
    
    @Transient
    private String albumName;
    
    @NotNull
    private boolean shared;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date created;
    
    @OneToMany(mappedBy = "parent", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)
    @org.hibernate.annotations.OrderBy(clause = "tag asc")
    private List<MetaTag> tags = new ArrayList<MetaTag>();
    
    @OneToMany(mappedBy = "image", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)
     @org.hibernate.annotations.OrderBy(clause="date asc")
    private List<Comment> comments = new ArrayList<Comment>();
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="IMG_ALBUM_ID",
    referencedColumnName="ALBUM_ID")
    private Album album;

	/**
	 * No-arg constructor for JavaBean tools
	 */
    public Image() {
    }
	
	/**
	 * Constructor
	 * 
	 * @param name - name of album
	 * @param parent - link for parent album
	 */
    public Image(String name) {
        this.name = name;
    }

	// ********************** Accessor Methods ********************** //

    /**
	 * Getter for property id
	 * 
	 * @return id of album
	 */
    public Long getId() {
        return id;
    }

    /**
	 * Getter for property name
	 * 
	 * @return name of album
	 */
    public String getName() {
        return name;
    }
    
    /**
	 * Getter for property version
	 * 
	 * @return version of current album object
	 */
    public int getVersion() {
        return version;
    }

	/**
	 * Setter for property name
	 * 
	 * @param name - name of album
	 */
    public void setName(String name) {
        this.name = name;
    }

	/**
	 * Getter for property description
	 * 
	 * @return description of album
	 */
    public String getDescription() {
        return description;
    }

	/**
	 * Setter for property description
	 * 
	 * @param description - description of album
	 */
    public void setDescription(String description) {
        this.description = description;
    }

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public boolean isShared() {
		return shared;
	}

	public void setShared(boolean shared) {
		this.shared = shared;
	}

	public Date getCreated() {
		return created;
	}

	public void setCreated(Date created) {
		this.created = created;
	}

	/*public Set<String> getTags() {
		return tags;
	}

	public void setTags(Set<String> tags) {
		this.tags = tags;
	}*/
	
	public Album getAlbum() {
		return album;
	}

	public void setAlbum(Album album) {
		this.album = album;
	}

	public String getAlbumName() {
		if(null == albumName && this.getAlbum() != null){
			albumName = this.getAlbum().getName();
		}
		return albumName;
	}

	public void setAlbumName(String albumName) {
		this.albumName = albumName;
	}

	public List<MetaTag> getTags() {
		return tags;
	}

	public void setTags(List<MetaTag> tags) {
		this.tags = tags;
	}
	
	//---------------------------Business methods

    public void addMetaTag(MetaTag metaTag) {
        if (metaTag == null) {
            throw new IllegalArgumentException("Null metaTag!");
        } 
        if (metaTag.getParent() != null && !this.equals(metaTag.getParent())) {
        	metaTag.getParent().getTags().remove(metaTag);
        }   
        metaTag.setParent(this);
        tags.add(metaTag);
    }

    public void removeMetaTag(MetaTag metaTag) {
        if (metaTag == null) {
            throw new IllegalArgumentException("Null metaTag");
        }  
        metaTag.setParent(null);
        tags.remove(metaTag);
    }
    
    public void addComment(Comment comment) {
        if (comment == null) {
            throw new IllegalArgumentException("Null comment!");
        } 
        if (comment.getImage() != null && !this.equals(comment.getImage())) {
        	comment.getImage().getComments().remove(comment);
        }   
        comment.setImage(this);
        comments.add(comment);
    }

    public void removeComment(Comment comment) {
        if (comment == null) {
            throw new IllegalArgumentException("Null comment");
        }  
        comment.setImage(null);
        comments.remove(comment);
    }

	public List<Comment> getComments() {
		return comments;
	}

	public void setComments(List<Comment> comments) {
		this.comments = comments;
	}

	public Rank getRank() {
		return rank;
	}

	public void setRank(Rank rank) {
		this.rank = rank;
	}
}
