package cz.muni.fi.pa165.entity;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

/**
 * Entity representing a single book in a library
 *
 * @author Michael Simacek
 *
 */
@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column
    private String authorName;

    @Column(nullable = false)
    private Long isbn;

    @Column(nullable = false)
    private BookState state = BookState.NEW;

    @ManyToMany(mappedBy = "books")
    private Set<BookCollection> collections = new HashSet<>();

    @OneToMany
    // OneToMany because we want to keep history of loans
    private Set<Loan> loans = new HashSet<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthorName() {
        return authorName;
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    public Long getIsbn() {
        return isbn;
    }

    public void setIsbn(Long isbn) {
        this.isbn = isbn;
    }

    public BookState getState() {
        return state;
    }

    public void setState(BookState state) {
        this.state = state;
    }

    public Set<BookCollection> getCollections() {
        return Collections.unmodifiableSet(collections);
    }

    public void addCollection(BookCollection collection) {
        collections.add(collection);
    }

    public Set<Loan> getLoans() {
        return loans;
    }

    public void setLoans(Set<Loan> loans) {
        this.loans = loans;
    }

    public void setCollections(Set<BookCollection> collections) {
        this.collections = collections;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((authorName == null) ? 0 : authorName.hashCode());
        result = prime * result + ((isbn == null) ? 0 : isbn.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Book))
            return false;
        Book other = (Book) obj;
        if (authorName == null) {
            if (other.authorName != null)
                return false;
        } else if (!authorName.equals(other.authorName))
            return false;
        if (isbn == null) {
            if (other.isbn != null)
                return false;
        } else if (!isbn.equals(other.isbn))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

@@ -2408,17 +2408,25 @@
     + ((
-a
+this.getA
 uthorNam
@@ -2418,32 +2418,34 @@
 is.getAuthorName
+()
  == null) ? 0 : 
@@ -2444,17 +2444,25 @@
 ) ? 0 : 
-a
+this.getA
 uthorNam
@@ -2462,16 +2462,18 @@
 thorName
+()
 .hashCod
@@ -2514,20 +2514,30 @@
 ult + ((
-isbn
+this.getIsbn()
  == null
@@ -2544,20 +2544,30 @@
 ) ? 0 : 
-isbn
+this.getIsbn()
 .hashCod
@@ -2608,20 +2608,30 @@
 ult + ((
-n
+this.getN
 ame
+()
  == null
@@ -2638,20 +2638,30 @@
 ) ? 0 : 
-n
+this.getN
 ame
+()
 .hashCod
@@ -2958,17 +2958,25 @@
     if (
-a
+this.getA
 uthorNam
@@ -2976,16 +2976,18 @@
 thorName
+()
  == null
@@ -3008,25 +3008,28 @@
   if (other.
-a
+getA
 uthorName !=
@@ -3025,16 +3025,18 @@
 thorName
+()
  != null
@@ -3087,17 +3087,25 @@
 se if (!
-a
+this.getA
 uthorNam
@@ -3105,16 +3105,18 @@
 thorName
+()
 .equals(
@@ -3121,17 +3121,20 @@
 s(other.
-a
+getA
 uthorNam
@@ -3134,16 +3134,18 @@
 thorName
+()
 ))%0A     
@@ -3177,20 +3177,30 @@
     if (
-isbn
+this.getIsbn()
  == null
@@ -3225,20 +3225,25 @@
  (other.
-i
+getI
 sbn
+()
  != null
@@ -3294,20 +3294,30 @@
 se if (!
-isbn
+this.getIsbn()
 .equals(
@@ -3322,20 +3322,25 @@
 s(other.
-i
+getI
 sbn
+()
 ))%0A     
@@ -3372,20 +3372,30 @@
     if (
-n
+this.getN
 ame
+()
  == null
@@ -3420,20 +3420,25 @@
  (other.
-n
+getN
 ame
+()
  != null
@@ -3489,20 +3489,30 @@
 se if (!
-n
+this.getN
 ame
+()
 .equals(
@@ -3517,20 +3517,25 @@
 s(other.
-n
+getN
 ame
+()
 ))%0A     

modify equlas and hascode methods in Loan class