/*
 * Answer.java
 *
 * Autor: Piotr Achinger <piotr.achinger at gmail.com>
 */
package dendrarium.core.entities;

import dendrarium.trees.AnswerType;
import java.io.Serializable;
import java.sql.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

/**
 *
 * @author pta
 */
@Entity
@NamedQueries({
    @NamedQuery(name = "myAnswersInProgress",
                query = "from Answer a where a.user=:user and a.accepted = false and a.taskBusinessProcess.current = TRUE and " +
    "a.taskBusinessProcess.superAnswer = null " +
    "order by a.taskBusinessProcess.packet.id, a.taskBusinessProcess.index"),
    /** moje gotowe odpowiedzi - te, które nie są na liście do potwierdzenia
     * TODO: zmienić nazwę np. na myAnswers - lub istotnie dodać jakiś recent
     */
    @NamedQuery(name = "myAnswers",
                query = "from Answer a where a.user=:user and " +
    "(a.taskBusinessProcess.superAnswer = null or a.taskBusinessProcess.superAnswer != a) and " +
    "(a.accepted = true or a.taskBusinessProcess.superAnswer != null) and " +
    "a.taskBusinessProcess.current = TRUE and " +
    "(a.taskBusinessProcess.state != dendrarium.core.entities.TaskBusinessProcessState.COLLISION or " +
    "a.confirmed = true) " +
    "order by a.taskBusinessProcess.packet.id, a.taskBusinessProcess.index"),
    /* moje odpowiedzi będące w kolizji z odpowiedzią drugiej osoby, wymagające potwierdzenia */
    @NamedQuery(name = "myAnswersToConfirm",
                query = "from Answer a where a.user=:user and a.taskBusinessProcess.current = TRUE and " +
    "a.taskBusinessProcess.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION and " +
    "a.confirmed = false " +
    "order by a.taskBusinessProcess.packet.id, a.taskBusinessProcess.index"),
    /* TODO: dodać kolejną listę z moimi odpowiedziami poprawionymi przez superdendrologa */
    /**
     * @author Tomasz Badowski
     *
     * Poniższe nazwy zbiorów zadań są wykorzystywane przy zbieraniu statystyk.
     * wszystkie przydzielone mi zadania - myAll
     * wszystkie zrobione zadania (łącznie z odpowiedziami specjalnymi) - myAllDone
     * dla ilu wybrał drzewo - myFull
     * dla ilu zdań wybrał odpowiedź specjalną - mySpecial
     * zrobione przeze mnie, czekające na odpowiedź drugiej osoby - onlyMineDone
     * zrobione przeze mnie, i przez drugą osobę - myAccepted
     */
    @NamedQuery(name = "myAllAnsNum1", /* przydzielone (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user"),
    @NamedQuery(name = "myAllAnsNum2", /* przydzielone (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user"),
    @NamedQuery(name = "myNotAccepted1",
                query= "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=false"),
    @NamedQuery(name = "myNotAccepted2",
                query= "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=false"),
    @NamedQuery(name = "myNeedConfNum1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and t.user1Answer.confirmed=false and " +
    "t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION"),
@NamedQuery(name = "myNeedConfNum2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and t.user2Answer.confirmed=false and " +
    "t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION"),
@NamedQuery(name = "myAllDoneAnsNum1", /* wykonane (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myAllDoneAnsNum2", /* wykonane (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myAgreements1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and t.state=dendrarium.core.entities.TaskBusinessProcessState.AUTOACCEPTED"),
@NamedQuery(name = "myAgreements2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and t.state=dendrarium.core.entities.TaskBusinessProcessState.AUTOACCEPTED"),
@NamedQuery(name = "myFullNum1", /* pełne rozbiory (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and t.user1Answer.type = dendrarium.trees.AnswerType.FULL and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myFullNum2", /* pełne rozbiory (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and t.user2Answer.type = dendrarium.trees.AnswerType.FULL and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myNoTree1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and t.user1Answer.type = dendrarium.trees.AnswerType.NO_TREE and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myNoTree2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and t.user2Answer.type = dendrarium.trees.AnswerType.NO_TREE and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myRejected1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and t.user1Answer.type not in (dendrarium.trees.AnswerType.FULL, dendrarium.trees.AnswerType.NO_TREE) and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myRejected2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and t.user2Answer.type not in (dendrarium.trees.AnswerType.FULL, dendrarium.trees.AnswerType.NO_TREE) and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "mySpecialNum1", /* odp. spec. (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and t.user1Answer.type != dendrarium.trees.AnswerType.FULL and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "mySpecialNum2", /* odp. spec. (d) */
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and t.user2Answer.type != dendrarium.trees.AnswerType.FULL and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "myCollisionsNum1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and (t.user1Answer.confirmed=true or t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and " +
    "(t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.INACCEPTANCE or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED)"),
@NamedQuery(name = "myCollisionsNum2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and (t.user2Answer.confirmed=true or t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and " +
    "(t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.INACCEPTANCE or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED)"),
@NamedQuery(name = "mySolved1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED"),
@NamedQuery(name = "mySolved2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED"),
@NamedQuery(name = "myRight1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user=:user and t.user1Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED and " +
    "exists (from Answer a where a=t.superAnswer and a.type=t.user1Answer.type and " +
    "a.answerHash=t.user1Answer.answerHash)"),
@NamedQuery(name = "myRight2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user=:user and t.user2Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED and " +
    "exists (from Answer a where a=t.superAnswer and a.type=t.user2Answer.type and " +
    "a.answerHash=t.user2Answer.answerHash)"),
    @NamedQuery(name = "nieprzydzielone1",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer = null"),
    @NamedQuery(name = "nieprzydzielone2",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user2Answer = null"),
    @NamedQuery(name = "myNieprzydzielone1",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer = null and t.user2Answer = null"),
    @NamedQuery(name = "myNieprzydzielone2",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer.user != :user and t.user2Answer = null"),
    @NamedQuery(name = "allAnsNum1",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer != null"),
    @NamedQuery(name = "allAnsNum2",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user2Answer != null"),
    @NamedQuery(name = "allNeedConfNum1",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer != null and t.user1Answer.accepted=true and t.user1Answer.confirmed = false and t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION"),
    @NamedQuery(name = "allNeedConfNum2",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user2Answer != null and t.user2Answer.accepted=true and t.user2Answer.confirmed = false and t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION"),
    @NamedQuery(name = "allDoneAnsNum1", /* wszystkie zrobione zadania (łącznie z odrzuconymi)*/

                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer != null and t.user1Answer.accepted=true and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
    @NamedQuery(name = "allDoneAnsNum2", /* wszystkie zrobione zadania (łącznie z odrzuconymi)*/

                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user2Answer != null and t.user2Answer.accepted=true and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
    @NamedQuery(name = "fullNum1",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer != null and t.user1Answer.accepted=true and t.user1Answer.type=dendrarium.trees.AnswerType.FULL and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
    @NamedQuery(name = "fullNum2",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user2Answer != null and t.user2Answer.accepted=true and t.user2Answer.type=dendrarium.trees.AnswerType.FULL and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
    @NamedQuery(name = "specialNum1",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user1Answer != null and t.user1Answer.accepted=true and t.user1Answer.type!=dendrarium.trees.AnswerType.FULL and t.user1Answer.confirmed = true"),
    @NamedQuery(name = "specialNum2",
                query = "select count(t) from TaskBusinessProcess t where t.current = true and t.user2Answer != null and t.user2Answer.accepted=true and t.user2Answer.type!=dendrarium.trees.AnswerType.FULL and t.user2Answer.confirmed = true"),
    @NamedQuery(name = "collisionsNum",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "(t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.INACCEPTANCE or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED)"),
@NamedQuery(name = "collisionsNum1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user != null and (t.user1Answer.confirmed=true or t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and " +
    "(t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.INACCEPTANCE or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED)"),
@NamedQuery(name = "collisionsNum2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user != null and (t.user2Answer.confirmed=true or t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and " +
    "(t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.INACCEPTANCE or " +
    "t.state = dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED)"),
    @NamedQuery(name = "notAccepted1",
                query= "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user != null and t.user1Answer.accepted=false"),
    @NamedQuery(name = "notAccepted2",
                query= "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user != null and t.user2Answer.accepted=false"),
@NamedQuery(name = "agreements1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user != null and t.user1Answer.accepted=true and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and t.state=dendrarium.core.entities.TaskBusinessProcessState.AUTOACCEPTED"),
@NamedQuery(name = "agreements2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user != null and t.user2Answer.accepted=true and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION) and t.state=dendrarium.core.entities.TaskBusinessProcessState.AUTOACCEPTED"),
@NamedQuery(name = "noTree1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user != null and t.user1Answer.accepted=true and t.user1Answer.type = dendrarium.trees.AnswerType.NO_TREE and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "noTree2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user != null and t.user2Answer.accepted=true and t.user2Answer.type = dendrarium.trees.AnswerType.NO_TREE and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "rejected1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user != null and t.user1Answer.accepted=true and t.user1Answer.type not in (dendrarium.trees.AnswerType.FULL, dendrarium.trees.AnswerType.NO_TREE) and (t.user1Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "rejected2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user != null and t.user2Answer.accepted=true and t.user2Answer.type not in (dendrarium.trees.AnswerType.FULL, dendrarium.trees.AnswerType.NO_TREE) and (t.user2Answer.confirmed=true or " +
    "t.state!=dendrarium.core.entities.TaskBusinessProcessState.COLLISION)"),
@NamedQuery(name = "solved1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user != null and t.user1Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED"),
@NamedQuery(name = "solved2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user != null and t.user2Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED"),
@NamedQuery(name = "right1",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user1Answer.user != null and t.user1Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED and " +
    "exists (from Answer a where a=t.superAnswer and a.type=t.user1Answer.type and " +
    "a.answerHash=t.user1Answer.answerHash)"),
@NamedQuery(name = "right2",
                query = "select count(t) from TaskBusinessProcess t where t.current=true and " +
    "t.user2Answer.user != null and t.user2Answer.accepted=true and t.state=dendrarium.core.entities.TaskBusinessProcessState.COLLISION_SOLVED and " +
    "exists (from Answer a where a=t.superAnswer and a.type=t.user2Answer.type and " +
    "a.answerHash=t.user2Answer.answerHash)"),
    @NamedQuery(name = "NumAnswersInterval",
                query = "select count(a) from Answer a where a.user=:user and a.accepted = true " +
    "and (a.selectDate >= :startDate) and (a.selectDate < :finishDate)"),
    @NamedQuery(name = "SuperNumAnswersInterval",
                query = "select count(t) from TaskBusinessProcess t where t.superAnswer.user=:user and t.superAnswer.accepted = true " +
    "and (t.superAnswer.selectDate >= :startDate) and (t.superAnswer.selectDate < :finishDate)")

})
public class Answer implements Serializable {

    /* === Poniższe pola umiejscawiają odpowiedź w systemie === */
    private Long id;

    private TaskBusinessProcess taskBusinessProcess;

    private User user;

    // TODO: zobaczyć, czemu ta adnotacja chce być przy polu
    @Temporal(TemporalType.DATE)
    private Date selectDate;

    /* === Merytoryczna zawartość odpowiedzi === */
    private String answer = null;

    private AnswerType type = AnswerType.FULL;

    private String comment = "";

    /* == Pola sterujące stanem odpowiedzi w systemie === */
    /**
     * Pole ozaczające, że odpowiedź jest zaakceptowana; w przeciwnym wypadku
     * zawartość pól answer oraz type jest traktowana jako kopia robocza
     */
    private boolean accepted = false;

    /**
     * Pole oznaczające, że użytkownik potwierdził swoją odpowiedź, będącą
     * w kolizji do odpowiedzi drugiego dendrologa
     */
    private boolean confirmed = false;

    /**
     * Pole oznaczające, że po zmianie gramatyki odpowiedź wymaga ponownej
     * edycji
     */
    private boolean refreshedByMUZG = false;

    private int answerHash = 0;

    /**
     * Sprawdzanie równoważności dwóch odpowiedzi - musi się zgadzać typ
     * odpowiedzi, a jeśli nie mamy do czynienia z odpowiedzią specjalną -
     * również treść odpowiedzi
     */
    public Boolean isEquivalentTo(Answer answer) {
        if (accepted == false || answer == null || answer.accepted == false) {
            return false;
        }
        if (type != answer.type) {
            return false;
        } else {
            switch (type) {
                case FULL:
                    return this.answerHash == answer.answerHash;
                default:
                    return true;
            }
        }
    }

    /**
     * Metody określające, czy dana odpowiedź jest odpowiedzią pierwszego,
     * czy drugiego dendrologa w danym zadaniu
     */
    @Transient
    public Boolean isFirstAnswer() {
        if (taskBusinessProcess.getUser1Answer() == null) {
            return false;
        }
        if (taskBusinessProcess.getUser1Answer().id == id) {
            return true;
        }
        return false;
    }

    @Transient
    public Boolean isSecondAnswer() {
        if (taskBusinessProcess.getUser2Answer() == null) {
            return false;
        }
        if (taskBusinessProcess.getUser2Answer().id == id) {
            return true;
        }
        return false;
    }

    public Boolean showIsRight() {
        return taskBusinessProcess.getState() ==
                TaskBusinessProcessState.COLLISION_SOLVED;
    }

    /**
     * Metoda zwracająca słowną odpowiedź na pytanie, czy odpowiedź dendrologa
     * została uznana przez superdendrologa po rozstrzygnięciu kolizji
     * Wołana tylko gdy TBP jest w stanie COLLISION_SOLVED
     * @author janek37
     * @return odpowiedź jako String
     */
    public String amIRight() {
        //assert showIsRight();
        if (isEquivalentTo(taskBusinessProcess.getSuperAnswer())) {
            return "RACJA";
        }
        return "NIERACJA";
    }

    /* === G & S === */
    public boolean isAccepted() {
        return accepted;
    }

    /**
     * Pole accepted określa, czy użytkownik zaakceptował już swoją odpowiedź,
     * czy jeszcze ją edytuje - musimy przy każdej zmianie adekwatnie zmieniać
     * stan zadania
     *
     */
    public void setAccepted(boolean accepted) {
        this.accepted = accepted;
    }

    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String getAnswer() {
        return answer;
    }

    /**
     * Przy zmianie odpowiedzi zmieniamy również jej hasz
     *
     */
    public void setAnswer(String answer) {
        this.answer = answer;
        if (answer != null) {
            setAnswerHash(answer.hashCode());
        } else {
            answerHash = 0;
        }
    }

    public int getAnswerHash() {
        return answerHash;
    }

    public void setAnswerHash(int answerHash) {
        this.answerHash = answerHash;
    }

    @Lob
    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public boolean isConfirmed() {
        return confirmed;
    }

    public void setConfirmed(boolean confirmed) {
        this.confirmed = confirmed;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    public Long getId() {
        return id;
    }

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

    public boolean isRefreshedByMUZG() {
        return refreshedByMUZG;
    }

    public void setRefreshedByMUZG(boolean refreshedByMUZG) {
        this.refreshedByMUZG = refreshedByMUZG;
    }

    public Date getSelectDate() {
        return selectDate;
    }

    public void setSelectDate(Date selectDate) {
        this.selectDate = selectDate;
    }

    @ManyToOne
    public TaskBusinessProcess getTaskBusinessProcess() {
        return taskBusinessProcess;
    }

    public void setTaskBusinessProcess(TaskBusinessProcess taskBusinessProcess) {
        this.taskBusinessProcess = taskBusinessProcess;
    }

//    @Enumerated(value = EnumType.ORDINAL)
    public AnswerType getType() {
        return type;
    }

    public void setType(AnswerType type) {
        this.type = type;
    }

    @ManyToOne
    @JoinColumn(name = "username")
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Answer[id=" + id + "]";
    }

    public String info() {
        return "HISTORIA: Answer " + id + ", user:" + (user == null? "null":user.getName())
                + ", type:" + (type == null? "null":type.toString())
                + ", tbp:" + (taskBusinessProcess == null? "null":taskBusinessProcess.getId())
                + ", accepted:" + accepted + ", confirmed:" + confirmed;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Answer)) {
            return false;
        }
        Answer other = (Answer) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0);
        hash = 17 * hash + (this.user != null ? this.user.hashCode() : 0);
        hash = 17 * hash + (this.comment != null ? this.comment.hashCode() : 0);
        //hash = 17 * hash + (this.taskBusinessProcess != null ? this.taskBusinessProcess.hashCode() : 0);
        hash = 17 * hash + (int) (this.answerHash ^ (this.answerHash >>> 32));
        return hash;
    }

    /* === konstruktory === */
    public Answer() {
    }

    public Answer(TaskBusinessProcess taskBusinessProcess) {
        this.taskBusinessProcess = taskBusinessProcess;
        this.answer = taskBusinessProcess.getTask().getForestXML();
    }

    public Answer(User user, TaskBusinessProcess taskBusinessProcess) {
        this.user = user;
        this.taskBusinessProcess = taskBusinessProcess;
        this.answer = taskBusinessProcess.getTask().getForestXML();
    }

    public Answer(Answer answer) {
        this.answer = answer.answer;
        this.comment = answer.comment;
        this.taskBusinessProcess = answer.taskBusinessProcess;
    }
}

