package cn.com.qmth.stmms.biz.exam.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.apache.commons.lang.StringUtils;

import cn.com.qmth.stmms.biz.utils.ScoreItem;
import cn.com.qmth.stmms.common.annotation.ExcelField;

/**
 * 针对某次考试的考生信息
 * 
 * @author LS
 * 
 */
@Entity
@Table(name = "eb_exam_student")
public class ExamStudent implements Serializable {

    protected static final long serialVersionUID = 2944870647483950851L;

    public static final String ANSWER_SPLIT = ",";

    public static final String SPLIT = ";";

    @Id
    @GeneratedValue
    private Integer id;

    /**
     * 考试ID
     */
    @Column(name = "exam_id")
    private Integer examId;

    /**
     * 学校ID
     */
    @Column(name = "school_id")
    private Integer schoolId;

    /**
     * 学习中心
     */
    @Column(name = "campus_name")
    @ExcelField(title = "学习中心", align = 2, sort = 10)
    private String campusName;

    /**
     * 科目代码
     */
    @Column(name = "subject_code")
    @ExcelField(title = "课程代码", align = 2, sort = 20)
    private String subjectCode;

    /**
     * 科目名称
     */
    @Column(name = "subject_name")
    @ExcelField(title = "课程名称", align = 2, sort = 30)
    private String subjectName;

    /**
     * 准考证号
     */
    @Column(name = "exam_number")
    @ExcelField(title = "准考证号", align = 2, sort = 40)
    private String examNumber;

    /**
     * 学号
     */
    @Column(name = "student_code")
    @ExcelField(title = "学号", align = 2, sort = 50)
    private String studentCode;

    /**
     * 姓名
     */
    @Column(name = "name")
    @ExcelField(title = "姓名", align = 2, sort = 60)
    private String name;

    /**
     * 试卷袋签到表编号
     */
    @Column(name = "package_code")
    @ExcelField(title = "签到表编号", align = 2, sort = 70)
    private String packageCode;

    /**
     * 考生考点信息
     */
    @Column(name = "exam_site")
    @ExcelField(title = "考点信息", align = 2, sort = 80)
    private String examSite;

    /**
     * 考生考场信息
     */
    @Column(name = "exam_room")
    @ExcelField(title = "考场信息", align = 2, sort = 90)
    private String examRoom;

    /**
     * 考生备注信息
     */
    @Column(name = "remark")
    @ExcelField(title = "考生备注信息", align = 2, sort = 100)
    private String remark;

    /**
     * 扫描批次编号
     */
    @Column(name = "batch_code")
    private String batchCode;

    /**
     * 原图数量
     */
    @Column(name = "sheet_count")
    private Integer sheetCount;

    /**
     * 小图数量
     */
    @Column(name = "slice_count")
    private Integer sliceCount;

    /**
     * 客观答案
     */
    @Column(name = "answers")
    private String answers;

    /**
     * 是否已上传
     */
    @Column(name = "is_upload")
    private boolean upload;

    /**
     * 是否缺考
     */
    @Column(name = "is_absent")
    private boolean absent;

    /**
     * 是否人工指定缺考
     */
    @Column(name = "is_manual_absent")
    private boolean manualAbsent;

    /**
     * 是否违纪
     */
    @Column(name = "is_breach")
    private boolean breach;

    /**
     * 是否数据校验异常
     */
    @Column(name = "is_exception")
    private boolean exception;

    /**
     * 上传时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "upload_time")
    private Date uploadTime;

    /**
     * 客观总分
     */
    @Column(name = "objective_score")
    private Double objectiveScore;

    /**
     * 客观题得分明细
     */
    @Column(name = "objective_score_list")
    private String objectiveScoreList;

    /**
     * 主观总分
     */
    @Column(name = "subjective_score")
    private Double subjectiveScore;

    /**
     * 主观题得分明细
     */
    @Column(name = "subjective_score_list")
    private String subjectiveScoreList;

    /**
     * 科目层次信息
     */
    @ExcelField(title = "层次", align = 2, sort = 110)
    @Column(name = "subject_level")
    private String subjectLevel;

    /**
     * 专业类型信息
     */
    @ExcelField(title = "专业类型", align = 2, sort = 120)
    @Column(name = "subject_category")
    private String subjectCategory;

    /**
     * 科目备注信息
     */
    @ExcelField(title = "科目备注信息", align = 2, sort = 130)
    @Transient
    private String subjectRemark;

    /**
     * 年级
     */
    @ExcelField(title = "年级", align = 2, sort = 140)
    private String grade;

    /**
     * 专业
     */
    @ExcelField(title = "专业", align = 2, sort = 150)
    private String department;

    @Transient
    private List<String> sheetUrls;

    @Transient
    private List<String> packageUrls;

    @Transient
    private String answerUrl;

    @Transient
    private String markTime;

    /**
     * 主观题是否已经评卷完成
     */
    @Transient
    private boolean marked;

    @Transient
    private int number;

    @Transient
    private String markLogin;

    @Transient
    private String markName;

    @Transient
    private String tagValue;

    public Integer getId() {
        return id;
    }

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

    public Integer getExamId() {
        return examId;
    }

    public void setExamId(Integer examId) {
        this.examId = examId;
    }

    public String getCampusName() {
        return campusName;
    }

    public void setCampusName(String campusName) {
        this.campusName = campusName;
    }

    public String getSubjectCode() {
        return subjectCode;
    }

    public void setSubjectCode(String subjectCode) {
        this.subjectCode = subjectCode;
    }

    public String getExamNumber() {
        return examNumber;
    }

    public void setExamNumber(String examNumber) {
        this.examNumber = examNumber;
    }

    public String getName() {
        return name;
    }

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

    public String getSubjectName() {
        return subjectName;
    }

    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }

    public String getStudentCode() {
        return studentCode;
    }

    public void setStudentCode(String studentCode) {
        this.studentCode = studentCode;
    }

    public String getAnswers() {
        return answers;
    }

    public void setAnswers(String answers) {
        this.answers = answers;
    }

    public boolean isUpload() {
        return upload;
    }

    public void setUpload(boolean upload) {
        this.upload = upload;
    }

    public Date getUploadTime() {
        return uploadTime;
    }

    public void setUploadTime(Date uploadTime) {
        this.uploadTime = uploadTime;
    }

    public List<String> getAnswerList() {
        String[] values = StringUtils.split(StringUtils.trimToNull(answers), ANSWER_SPLIT);
        List<String> list = new ArrayList<String>();
        if (values != null && values.length > 0) {
            for (String answer : values) {
                list.add(StringUtils.trim(answer));
            }
        }
        return list;
    }

    public Double getObjectiveScore() {
        return objectiveScore;
    }

    public void setObjectiveScore(Double objectiveScore) {
        this.objectiveScore = objectiveScore;
    }

    public Double getSubjectiveScore() {
        return subjectiveScore;
    }

    public void setSubjectiveScore(Double subjectiveScore) {
        this.subjectiveScore = subjectiveScore;
    }

    public String getObjectiveScoreList() {
        return objectiveScoreList;
    }

    public void setObjectiveScoreList(String objectiveScoreList) {
        this.objectiveScoreList = objectiveScoreList;
    }

    public String getSubjectiveScoreList() {
        return subjectiveScoreList;
    }

    public void setSubjectiveScoreList(String subjectiveScoreList) {
        this.subjectiveScoreList = subjectiveScoreList;
    }

    public static String buildScoreList(List<ScoreItem> scoreList) {
        if (scoreList != null) {
            return StringUtils.join(scoreList, SPLIT);
        } else {
            return null;
        }
    }

    public void setScoreList(List<ScoreItem> scoreList, boolean objective) {
        if (scoreList != null) {
            if (objective) {
                setObjectiveScoreList(StringUtils.join(scoreList, SPLIT));
            } else {
                setSubjectiveScoreList(StringUtils.join(scoreList, SPLIT));
            }
        }
    }

    public List<ScoreItem> getScoreList(boolean objective) {
        List<ScoreItem> scoreList = new LinkedList<ScoreItem>();
        try {
            String[] values = StringUtils.split(objective ? objectiveScoreList : subjectiveScoreList, SPLIT);
            for (String value : values) {
                ScoreItem item = ScoreItem.parse(value, objective);
                item.setObjective(objective);
                if (item != null) {
                    scoreList.add(item);
                }
            }
        } catch (Exception e) {
        }
        return scoreList;
    }

    public List<String> getSheetUrls() {
        return sheetUrls;
    }

    public void setSheetUrls(List<String> sheetUrls) {
        this.sheetUrls = sheetUrls;
    }

    public boolean isAbsent() {
        return absent;
    }

    public void setAbsent(boolean absent) {
        this.absent = absent;
    }

    public boolean isBreach() {
        return breach;
    }

    public void setBreach(boolean breach) {
        this.breach = breach;
    }

    public boolean isManualAbsent() {
        return manualAbsent;
    }

    public void setManualAbsent(boolean manualAbsent) {
        this.manualAbsent = manualAbsent;
    }

    public Integer getSheetCount() {
        return sheetCount;
    }

    public void setSheetCount(Integer sheetCount) {
        this.sheetCount = sheetCount;
    }

    public Integer getSliceCount() {
        return sliceCount;
    }

    public void setSliceCount(Integer sliceCount) {
        this.sliceCount = sliceCount;
    }

    public double getTotalScore() {
        double score = 0;
        if (objectiveScore != null) {
            score += objectiveScore;
        }
        if (subjectiveScore != null) {
            score += subjectiveScore;
        }
        return score;
    }

    public Integer getSchoolId() {
        return schoolId;
    }

    public void setSchoolId(Integer schoolId) {
        this.schoolId = schoolId;
    }

    public String getBatchCode() {
        return batchCode;
    }

    public void setBatchCode(String batchCode) {
        this.batchCode = batchCode;
    }

    public String getPackageCode() {
        return packageCode;
    }

    public void setPackageCode(String packageCode) {
        this.packageCode = packageCode;
    }

    public List<String> getPackageUrls() {
        return packageUrls;
    }

    public void setPackageUrls(List<String> packageUrls) {
        this.packageUrls = packageUrls;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getMarkTime() {
        return markTime;
    }

    public void setMarkTime(String markTime) {
        this.markTime = markTime;
    }

    public boolean isException() {
        return exception;
    }

    public void setException(boolean exception) {
        this.exception = exception;
    }

    public String getObjectiveScoreString() {
        try {
            return ScoreItem.NUMBER_FORMAT.format(objectiveScore);
        } catch (Exception e) {
            return "";
        }
    }

    public String getSubjectiveScoreString() {
        try {
            return ScoreItem.NUMBER_FORMAT.format(subjectiveScore);
        } catch (Exception e) {
            return "";
        }
    }

    public String getTotalScoreString() {
        try {
            return ScoreItem.NUMBER_FORMAT.format(getTotalScore());
        } catch (Exception e) {
            return "";
        }
    }

    public String getSubjectRemark() {
        return subjectRemark;
    }

    public void setSubjectRemark(String subjectRemark) {
        this.subjectRemark = subjectRemark;
    }

    public String getSheetUrlString() {
        if (sheetUrls != null) {
            return StringUtils.join(sheetUrls, ",");
        } else {
            return "";
        }
    }

    public String getPackageUrlString() {
        if (packageUrls != null) {
            return StringUtils.join(packageUrls, ",");
        } else {
            return "";
        }
    }

    public String getAnswerUrl() {
        return answerUrl;
    }

    public void setAnswerUrl(String answerUrl) {
        this.answerUrl = answerUrl;
    }

    public String getSubjectLevel() {
        return subjectLevel;
    }

    public void setSubjectLevel(String subjectLevel) {
        this.subjectLevel = subjectLevel;
    }

    public String getExamSite() {
        return examSite;
    }

    public void setExamSite(String examSite) {
        this.examSite = examSite;
    }

    public String getExamRoom() {
        return examRoom;
    }

    public void setExamRoom(String examRoom) {
        this.examRoom = examRoom;
    }

    public String getSubjectCategory() {
        return subjectCategory;
    }

    public void setSubjectCategory(String subjectCategory) {
        this.subjectCategory = subjectCategory;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public boolean isMarked() {
        return marked;
    }

    public void setMarked(boolean marked) {
        this.marked = marked;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public String getMarkLogin() {
        return markLogin;
    }

    public void setMarkLogin(String markLogin) {
        this.markLogin = markLogin;
    }

    public String getMarkName() {
        return markName;
    }

    public void setMarkName(String markName) {
        this.markName = markName;
    }

    public String getTagValue() {
        return tagValue;
    }

    public void setTagValue(String tagValue) {
        this.tagValue = tagValue;
    }

}
