import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.ArrayList;

/**
 * Created by shumailovr on 23.04.15.
 */

@Entity
@Table(name = "book_difference")
public class BookDifferenceModel {

    private BookDifferenceModelId bookDifferenceModelId;
    private double difference;

    public BookDifferenceModel() {
    }

    public BookDifferenceModel(BookDifferenceModelId bookDifferenceModelId, double difference) {
        this.bookDifferenceModelId = bookDifferenceModelId;
        this.difference = difference;
    }

    @EmbeddedId
    public BookDifferenceModelId getBookDifferenceModelId() {
        return bookDifferenceModelId;
    }

    public void setBookDifferenceModelId(BookDifferenceModelId bookDifferenceModelId) {
        this.bookDifferenceModelId = bookDifferenceModelId;
    }

    @Column(name = "difference")
    public double getDifference() {
        return difference;
    }

    public void setDifference(double difference) {
        this.difference = difference;
    }

    /**
     * Calculates and saves book pair differences for testing
     */
    public static void calculateAndSaveBookDifferences() {
        PersistenceManager persistenceManager = new PersistenceManager();

        //Get regressors' parameters
        RegressorParameterModel interceptTerm = persistenceManager.getParameterByName("intercept");
        RegressorParameterModel averSentenceRegressor = persistenceManager.getParameterByName("averSentenceLength");
        RegressorParameterModel averWordLengthRegressor = persistenceManager.getParameterByName("averWordLength");
        RegressorParameterModel charSumRegressor = persistenceManager.getParameterByName("characters");
        RegressorParameterModel datesSumRegressor = persistenceManager.getParameterByName("dates");
        RegressorParameterModel locationsSumRegressor = persistenceManager.getParameterByName("locations");
        RegressorParameterModel namesSumRegressor = persistenceManager.getParameterByName("names");
        RegressorParameterModel relAdjNumRegressor = persistenceManager.getParameterByName("relAdjectives");
        RegressorParameterModel relNounsNumRegressor = persistenceManager.getParameterByName("relNouns");
        RegressorParameterModel relVerbsNumRegressor = persistenceManager.getParameterByName("relVerbs");
        RegressorParameterModel sentencesSumRegressor = persistenceManager.getParameterByName("sentences");
        RegressorParameterModel positivenessRegressor = persistenceManager.getParameterByName("positiveness");
        RegressorParameterModel wordsSumRegressor = persistenceManager.getParameterByName("words");

        ArrayList<AnalyzedBookModel> analyzedBooks = persistenceManager.getAnalyzedBooks();

        for (AnalyzedBookModel analyzedBook1 : analyzedBooks) {
            ArrayList<AnalyzedBookModel> otherAnalyzedBooks = persistenceManager.getAnalyzedBooksExcludeByTitleAndAuthor(
                    analyzedBook1.getAnalyzedBookModelId().getTitle(), analyzedBook1.getAnalyzedBookModelId().getAuthor()
            );
            String isbn1 = persistenceManager.getBXIsbnByTitleAndAuthor(analyzedBook1.getAnalyzedBookModelId().getTitle(),
                    analyzedBook1.getAnalyzedBookModelId().getAuthor());
            for (AnalyzedBookModel analyzedBook2 : otherAnalyzedBooks) {
                String isbn2 = persistenceManager.getBXIsbnByTitleAndAuthor(analyzedBook2.getAnalyzedBookModelId().getTitle(),
                        analyzedBook2.getAnalyzedBookModelId().getAuthor());

                System.out.println("**********************************");
                System.out.println("NEW ENTRY");
                System.out.println("**********************************");
                //Form new regressors vector for this book pair
                double averSentenceLength = Math.abs(analyzedBook1.getAverSentenceLength() - analyzedBook2.getAverSentenceLength());
                double averWordLength = Math.abs(analyzedBook1.getAverWordLength() - analyzedBook2.getAverWordLength());
                double charSum = Math.abs(analyzedBook1.getCharactersNum() - analyzedBook2.getCharactersNum());
                double datesSum = Math.abs(analyzedBook1.getDates() - analyzedBook2.getDates());
                double locationsSum = Math.abs(analyzedBook1.getLocations() - analyzedBook2.getLocations());
                double namesSum = Math.abs(analyzedBook1.getNames() - analyzedBook2.getNames());
                double wordsSum = Math.abs(analyzedBook1.getWordsNum() - analyzedBook2.getWordsNum());
                double relAdjNum = Math.abs(analyzedBook1.getRelAdjectives() - analyzedBook2.getRelAdjectives());
                double relNounsNum = Math.abs(analyzedBook1.getRelNouns() - analyzedBook2.getRelNouns());
                double relVerbsNum = Math.abs(analyzedBook1.getRelVerbs() - analyzedBook2.getRelVerbs());
                double sentencesSum = Math.abs(analyzedBook1.getSentencesNum() - analyzedBook2.getSentencesNum());
                double positiveness = Math.abs(analyzedBook1.getPositiveness() - analyzedBook2.getPositiveness());

                //Calculate difference
                double difference = averSentenceRegressor.getParameter() * averSentenceLength +
                        averWordLengthRegressor.getParameter() * averWordLength +
                        charSumRegressor.getParameter() * charSum +
                        datesSumRegressor.getParameter() * datesSum +
                        locationsSumRegressor.getParameter() * locationsSum +
                        namesSumRegressor.getParameter() * namesSum +
                        wordsSumRegressor.getParameter() * wordsSum +
                        relAdjNumRegressor.getParameter() * relAdjNum +
                        relNounsNumRegressor.getParameter() * relNounsNum +
                        relVerbsNumRegressor.getParameter() * relVerbsNum +
                        sentencesSumRegressor.getParameter() * sentencesSum +
                        positivenessRegressor.getParameter() * positiveness +
                        interceptTerm.getParameter();

                //Save book pair difference
                persistenceManager.saveBookDifference(new BookDifferenceModel(new BookDifferenceModelId(isbn1, isbn2), difference));
            }
        }
    }
}
