/*
 * Album.java
 * Last modified by: $Author: amarkhel $
 * $Revision: 11460 $	$Date: 2008-12-01 18:45:22 +0200 $
 */
package org.richfaces.realworld.domain;

import java.io.Serializable;
import java.util.ArrayList;
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.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
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 Album Entity
 *  EJB3 Entity Bean
 * 
 * @author Andrey Markhel
 */
@Entity
@Name("album")
@Scope(ScopeType.PAGE)
@Table(name = "albums")
public class Album implements Serializable {

    private static final long serialVersionUID = -7042878411608396483L;

    @Id
    @GeneratedValue
    @Column(name = "ALBUM_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)
    @NotNull
	@NotEmpty
    @Length(min=3)
    private String description;

    /*@OneToMany(mappedBy = "parent", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)
    @org.hibernate.annotations.OrderBy(clause = "NAME asc")
    private List<Album> childAlbums = new ArrayList<Album>();

    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name = "PARENT_ID", nullable = true)
    @org.hibernate.annotations.ForeignKey(name = "FK_PARENT_ID")
    private Album parent;*/
    
    @ManyToOne
    @JoinColumn(name="ALBUM_USER_ID",
    referencedColumnName="USER_ID")
    private User owner;

    @NotNull
    private boolean shared;
    
    @Transient 
    private String changedName;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "album")
    @org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
    private List<Image> images = new ArrayList<Image>();
    
    @ManyToMany
    @JoinTable(
        name = "SHARED_ALBUMS",
        joinColumns =        @JoinColumn(name = "ALBUM_ID"),
        inverseJoinColumns = @JoinColumn(name = "USER_ID")
    )
    private List<User> sharedOwners = new ArrayList<User>();
    
	/**
	 * No-arg constructor for JavaBean tools
	 */
    public Album() {
    }
	
	/**
	 * Constructor
	 * 
	 * @param name - name of album
	 * @param parent - link for parent album
	 */
    public Album(String name) {
        this.name = name;
        //this.parent = parent;
    }

	// ********************** 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 childAlbums
	 * 
	 * @return list of childs  of current albums
	 *//*
    public List<Album> getChildAlbums() {
        return childAlbums;
    }
	
	*//**
	 * Getter for property parent
	 * 
	 * @return parent of album
	 *//*
    public Album getParent() {
        return parent;
    }

	*//**
	 * Setter for property parent
	 *//*
    private void setParent(Album parent) {
        this.parent = parent;
    }*/

	/**
	 * 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;
    }
	
	// ********************** Business Methods ********************** //

	/**
	 * This method add image to collection of images of current album
	 * 
	 * @param image - image to add
	 */
    public void addImage(Image image) {
        if (image == null) {
            throw new IllegalArgumentException("Null image!");
        } 
        if (image.getAlbum() != null && !this.equals(image.getAlbum())) {
            image.getAlbum().getImages().remove(image);
        }   
        image.setAlbum(this);
        images.add(image);
    }

	/**
	 * This method remove image from collection of images of album
	 * 
	 * @param image - image to remove
	 */
    public void removeImage(Image image) {
        if (image == null) {
            throw new IllegalArgumentException("Null image");
        }  
        image.setAlbum(null);
        images.remove(image);
    }

	/**
	 * This method return count of images of current album
	 * 
	 * @return count of images of this album
	 */
    public int getCountImages() {
        return this.getImages()!= null ? this.getImages().size() : 0;

    }

	public boolean isShared() {
		return shared;
	}

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

	public User getOwner() {
		return owner;
	}

	public List<Image> getImages() {
		return images;
	}

	public void setOwner(User owner) {
		this.owner = owner;
	}

	public String getChangedName() {
		if(changedName != null){
			return changedName;
		}
		return this.getName();
	}

	public void setChangedName(String changedName) {
		this.changedName = changedName;
	}

	public List<User> getSharedOwners() {
		return sharedOwners;
	}

	public void setSharedOwners(List<User> sharedOwners) {
		this.sharedOwners = sharedOwners;
	}

	public int getIndex(Image image) {
		for(int i =0; i < this.images.size(); i++){
			if(this.images.get(i).equals(image)){
				return i;
			}
		}
		return -1;
	}
}
