package com.artursworld.nccn.model.entity;

import android.util.Log;

import com.artursworld.nccn.controller.util.Bits;
import com.artursworld.nccn.controller.util.Questionnairy;

import java.util.Date;
import java.util.Map;

/**
 * Represents the Quality Of Life (Qol) Questionnaire
 */
public class QolQuestionnaire {

    private Date creationDate_PK;
    private String userNameId_FK;
    private Date updateDate;
    private byte[] answersToQuestionsBytes;

    // configuration
    private int questionByteCount = 26;
    public static String defaultByte = "00010001";
    public static String exceptionalByte = "00000001";

    public QolQuestionnaire(String userNameId){
        this.userNameId_FK = userNameId;
        this.creationDate_PK = new Date();
        this.updateDate = new Date();

        // init answer bytes
        answersToQuestionsBytes = new byte[questionByteCount];
        int index = 0;
        for(; index < 14 ; index++){
            answersToQuestionsBytes[index] = Bits.getByteByString(defaultByte)[0];
        }
        answersToQuestionsBytes[index++] = Bits.getByteByString(exceptionalByte)[0];
        answersToQuestionsBytes[index++] = Bits.getByteByString(exceptionalByte)[0];
        for(; index < 26 ; index++){
            answersToQuestionsBytes[index] = Bits.getByteByString(defaultByte)[0];
        }
    }

    public String getBitsByQuestionNr(int questionNr){
        if (validateQuestionNr(questionNr)) return null;
        StringBuilder result = new StringBuilder(Bits.getStringByByte(answersToQuestionsBytes));
        int[] startEndIndices = getStartEndIndexByQuestionNr(questionNr);
        return result.substring(startEndIndices[0], startEndIndices[1]);
    }

    //TODO: get Bits by question Nr. and set Bits by quest Nr.
    public void setBitsByQuestionNr(int questionNr, String newBits) {
        if (validateQuestionNr(questionNr)) return;

        if(questionNr == 29 || questionNr == 30)
            if (newBits.length() != 8){
                Log.e(QolQuestionnaire.class.getSimpleName(), "setBitsByQuestionNr accepts only bits of length 8 if quesitonNr = 29 or 30");
                return;
            }

        if(questionNr != 29 && questionNr !=30)
            if (newBits.length() !=4){
                Log.e(QolQuestionnaire.class.getSimpleName(), "setBitsByQuestionNr accepts only bits of length 4 if quesitonNr != 29 or 30");
                return;
            }

        StringBuilder result = new StringBuilder(Bits.getStringByByte(answersToQuestionsBytes));
        int[] startEndIndices = getStartEndIndexByQuestionNr(questionNr);
        result.replace(startEndIndices[0], startEndIndices[1], newBits);
        this.setAnswersToQuestionsBytes(Bits.getByteByString(result.toString()));
    }

    /**
     * Accepts only question number between 1 and 50
     * @param questionNr the question number to validate
     * @return False if validatation fails, otherwise true
     */
    private boolean validateQuestionNr(int questionNr) {
        if(questionNr < 1 || questionNr > 50){
            Log.e(QolQuestionnaire.class.getSimpleName(), "getBitsByQuestionNr accepts only numbers between [1 - 50]");
            return true;
        }
        return false;
    }

    /**
     * Calculates the beginning index, inclusive and the ending index, exclusive
     * of the question by question number
     * @param questionNr the question number
     * @return an array containing the beginning and ending index
     */
    private int[] getStartEndIndexByQuestionNr(int questionNr) {
        int [] indexStartEnd = new int[2];
        int beginningIndex = 0;
        int endingIndex = 0;
        if(questionNr < 29){
            questionNr = questionNr -1;
            beginningIndex = (questionNr * 4);
            endingIndex = beginningIndex + 4;
        }
        else if( questionNr == 29){
            beginningIndex = (28 * 4);
            endingIndex = beginningIndex + 8;
        }
        else if( questionNr == 30){
            beginningIndex = (28 * 4) + 8;
            endingIndex = beginningIndex + 8;
        }
        else if(questionNr > 30){
            questionNr = questionNr -1;
            int restIndex = ((questionNr - 28) * 4) -  8;
            beginningIndex = (28 * 4) + (2 * 8) + restIndex;
            endingIndex = beginningIndex + 4;
        }
        indexStartEnd[0] = beginningIndex;
        indexStartEnd[1] = endingIndex;
        return indexStartEnd;
    }

    public Date getCreationDate_PK() {
        return creationDate_PK;
    }

    public void setCreationDate_PK(Date creationDate_PK) {
        this.creationDate_PK = creationDate_PK;
    }

    public String getUserNameId_FK() {
        return userNameId_FK;
    }

    public void setUserNameId_FK(String userNameId_FK) {
        this.userNameId_FK = userNameId_FK;
    }

    public Date getUpdateDate() {
        return updateDate;
    }

    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }

    public byte[] getAnswersToQuestionsBytes() {
        return answersToQuestionsBytes;
    }

    public String getAnswersToQuestionsAsString(){
        return Bits.getStringByByte(this.answersToQuestionsBytes);
    }

    public void setAnswersToQuestionsBytes(byte[] answersToQuestionsBytes) {
        this.answersToQuestionsBytes = answersToQuestionsBytes;
    }
}

@@ -1719,101 +1719,872 @@
    /
-/TODO: get Bits by question Nr. and set Bits by quest Nr.%0A    public void setBitsByQuestionNr
+**%0A     * Sets new bits to the question by question number (first nr. 1 and last 50)%0A     * @param questionNr the question number%0A     * @param newBits the new bits to set%0A     */%0A    public void setBitsByQuestionNr(int questionNr, String newBits) %7B%0A        if (validateInput(questionNr, newBits)) return;%0A%0A        // get current byte string%0A        StringBuilder result = new StringBuilder(Bits.getStringByByte(answersToQuestionsBytes));%0A%0A        // get indices of bits pattern to replace%0A        int%5B%5D startEndIndices = getStartEndIndexByQuestionNr(questionNr);%0A%0A        // replace bit pattern%0A        result.replace(startEndIndices%5B0%5D, startEndIndices%5B1%5D, newBits);%0A%0A        // set new results to real byte array using the string of bytes%0A        this.setAnswersToQuestionsBytes(Bits.getByteByString(result.toString()));%0A    %7D%0A%0A    private boolean validateInput
 (int
@@ -2656,32 +2656,37 @@
 stionNr)) return
+ true
 ;%0A%0A        if(qu
@@ -2916,32 +2916,37 @@
           return
+ true
 ;%0A            %7D%0A
@@ -3201,349 +3201,49 @@
 turn
-;%0A            %7D%0A%0A        StringBuilder result = new StringBuilder(Bits.getStringByByte(answersToQuestionsBytes));%0A        int%5B%5D startEndIndices = getStartEndIndexByQuestionNr(questionNr);%0A        result.replace(startEndIndices%5B0%5D, startEndIndices%5B1%5D, newBits);%0A        this.setAnswersToQuestionsBytes(Bits.getByteByString(result.toString()))
+ true;%0A            %7D%0A        return false
 ;%0A  

refactor the code