package com.bernard.mcqinator.api;

import android.app.Activity;
import android.support.annotation.Nullable;

import com.bernard.mcqinator.R;
import com.bernard.mcqinator.api.fragenStats.FormQuizStat;
import com.bernard.mcqinator.api.fragenStats.QuizStat;
import com.bernard.mcqinator.api.quiz.DEVerbenQuiz;
import com.bernard.mcqinator.api.quiz.Quiz;
import com.bernard.mcqinator.view.activities.congratsActivity.DEVerbenCongratsActivity;
import com.bernard.mcqinator.view.quizEditing.formQuiz.EditFormQuiz;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;

public class QuizMetadata implements Serializable {



    private String name;
    private String author;
    private long fileID;
    private Type type;
    private boolean editable;

    public QuizMetadata(String name, String author, long fileID, Type type, boolean editable) {
        this.name = name;
        this.author = author;
        this.fileID = fileID;
        this.type = type;
        this.editable = editable;
    }

    public QuizMetadata() {}// For serialization


    //////////// File methods ////////////

    public void read(DataInputStream fin) throws IOException{
        byte[] nameBytes = new byte[fin.readInt()];
        if(fin.read(nameBytes) != nameBytes.length)throw new IOException("Corrupted data : announced name bytes count dont match found");
        this.name = new String(nameBytes);
        byte[] authorBytes = new byte[fin.readInt()];
        if(fin.read(authorBytes) != authorBytes.length)throw new IOException("Corrupted data : announced author bytes count dont match found");
        this.author = new String(authorBytes);
        this.fileID = fin.readLong();
        this.type = Type.getTypeFromID(fin.readInt());
        this.editable = fin.readBoolean();
    }

    public void write(DataOutputStream fos) throws IOException{
        fos.writeInt(this.name.getBytes().length);
        fos.write(this.name.getBytes());
        fos.writeInt(this.author.getBytes().length);
        fos.write(this.author.getBytes());
        fos.writeLong(this.fileID);
        fos.writeInt(this.type.getId());
        fos.writeBoolean(this.editable);
    }


    //////////// Getters and Setters ////////////


    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public long getFileID() {
        return fileID;
    }

    public void setFileID(long fileID) {
        this.fileID = fileID;
    }

    public Type getType() {
        return type;
    }

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

    public boolean isEditable() {
        return editable;
    }

    public void setEditable(boolean editable) {
        this.editable = editable;
    }


    //////////// Internal Classes ////////////

    public enum Type{
        DEVerben(DEVerbenQuiz.class, FormQuizStat.class, EditFormQuiz.class, DEVerbenCongratsActivity.class, R.drawable.de_verben_quiz,0);

        final Class<? extends Quiz> quizClass;
        final Class<? extends QuizStat> quizStatClass;
        final Class<? extends Activity> editActivityClass;
        final Class<? extends Activity> congratsActivityClass;
        final int quizIconID;
        final int id;

        Type(Class<? extends Quiz> quizClass, Class<? extends QuizStat> quizStatClass, Class<? extends Activity> editActivityClass, Class<? extends Activity> congratsActivityClass, int quizIconID, int id) {
            this.quizClass = quizClass;
            this.quizStatClass = quizStatClass;
            this.editActivityClass = editActivityClass;
            this.congratsActivityClass = congratsActivityClass;
            this.quizIconID = quizIconID;
            this.id = id;
        }

        Type(Class<? extends Quiz> quizClass, Class<? extends QuizStat> quizStatClass, Class<? extends Activity> editActivityClass, Class<? extends Activity> congratsActivityClass, int id) {
            this(quizClass,quizStatClass,editActivityClass,congratsActivityClass,R.drawable.default_quiz_icon,id);
        }

        public Class<? extends Quiz> getQuizClass() {
            return quizClass;
        }

        public Class<? extends QuizStat> getQuizStatClass() {
            return quizStatClass;
        }

        public Class<? extends Activity> getEditActivityClass() {
            return editActivityClass;
        }

        public Class<? extends Activity> getCongratsActivityClass(){
            return congratsActivityClass;
        }

        public int getQuizIconID() {
            return quizIconID;
        }

        public int getId() {
            return id;
        }

        @Nullable
        public static Type getTypeFromID(int id){
            for (Type t:Type.values()) {
                if(t.getId() == id)
                    return t;
            }
            return null;
        }
    }


    //////////// Misc ///////////

    @Override
    public String toString() {
        return "QuizMetadata{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", fileID=" + fileID +
                ", type=" + type +
                ", editable=" + editable +
                '}';
    }
}