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

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
import cn.com.qmth.stmms.biz.exam.model.InspectHistory;
import cn.com.qmth.stmms.biz.utils.ScoreItem;
import cn.com.qmth.stmms.common.annotation.ExcelField;
import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
import cn.com.qmth.stmms.common.utils.BigDecimalUtils;

public class ExamStudentVo {

    public static final String ANSWER_SPLIT = ",";

    public static final String SPLIT = ";";


    private Integer id;

    /**
     * 考试ID
     */
    private Integer examId;

    /**
     * 学校ID
     */
    private Integer schoolId;

    /**
     * 学习中心
     */
    private String campusName;

    /**
     * 科目代码
     */
    @ExcelField(title = "科目代码*", align = 2, sort = 1)
    private String subjectCode;

    /**
     * 科目名称
     */
    @ExcelField(title = "科目名称*", align = 2, sort = 2)
    private String subjectName;

    /**
     * 试卷类型
     */
    private String paperType;

    /**
     * 准考证号
     */
    private String examNumber;

    /**
     * 学号
     */
    private String studentCode;

    /**
     * 密号
     */
    @ExcelField(title = "密号*", align = 2, sort = 3)
    private String secretNumber;

    /**
     * 姓名
     */
    private String name;

    /**
     * 试卷袋签到表编号
     */
    private String packageCode;

    /**
     * 考生考点信息
     */
    private String examSite;

    /**
     * 考生考场信息
     */
    private String examRoom;

    /**
     * 考生备注信息
     */
    private String remark;

    /**
     * 扫描批次编号
     */
    private String batchCode;

    /**
     * 原图数量
     */
    private Integer sheetCount;

    /**
     * 裁切图数量
     */
    private Integer sliceCount;

    /**
     * 客观答案
     */
    private String answers;

    /**
     * 是否已上传
     */
    private boolean upload;

    /**
     * 是否缺考
     */
    private boolean absent;

    /**
     * 是否人工指定缺考
     */
    private boolean manualAbsent;

    private boolean breach;

    /**
     * 是否数据校验异常
     */
    private boolean exception;

    /**
     * 上传时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date uploadTime;

    /**
     * 客观总分
     */
    private Double objectiveScore;

    /**
     * 客观题得分明细
     */
    @ExcelField(title = "客观明细*", align = 2, sort =7)
    private String objectiveScoreList;

    /**
     * 主观题状态
     */
    @Enumerated(EnumType.STRING)
    private SubjectiveStatus subjectiveStatus;

    /**
     * 主观总分
     */
    private Double subjectiveScore;
    
    
    @ExcelField(title = "客观分*", align = 2, sort = 4)
    private String objectiveScoreString;
    
    @ExcelField(title = "主观分*", align = 2, sort = 5)
    private String subjectiveScoreString;
    @ExcelField(title = "试卷总分*", align = 2, sort = 6)
    private String totalScoreString;

    /**
     * 主观题得分明细
     */
    @ExcelField(title = "得分明细*", align = 2, sort =8)
    private String subjectiveScoreList;

    /**
     * 科目层次信息
     */
    private String subjectLevel;

    /**
     * 专业类型信息
     */
    private String subjectCategory;

    /**
     * 电厂
     */
    private String college;

    /**
     * 机组
     */
    private String className;

    /**
     * 总评
     */
    private String teacher;

    @Temporal(TemporalType.TIMESTAMP)
    private Date inspectTime;

    /**
     * 复核人id
     */
    private Integer inspectorId;

    private Integer cardNumber;

    private Integer inspectCount;
    
    /**
     * 当前轮次是否已复核
     */
    private boolean inspected;
    
    /**
     * 成绩校验人ID
     */
    private Integer scoreVerifyUser;
    
    /**
     * 成绩校验时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date scoreVerifyTime;
    
    /**
     * 成绩校验标记结果
     */
    private Boolean scoreVerifyFlagged;
    

    /**
     * 科目备注信息
     */
    private String subjectRemark;

    private List<String> sheetUrls;

    private List<String> packageUrls;

    private String answerUrl;

    private String markTime;

    private Integer libraryId;

    private int number;

    private String markLogin;

    private String markName;

    private String tagValue;

    private String examName;

    private List<ExamQuestion> subjectiveQuestionList;

    private List<ExamQuestion> objectiveQuestionList;

    private String problemUserName;

    private String problemRestTime;

    private Map<String,InspectHistory> inspectHistoryMap;
    
    private Boolean selective;

    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 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 = BigDecimalUtils.add(score, objectiveScore);
        }
        if (subjectiveScore != null) {
            score = BigDecimalUtils.add(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 Integer getLibraryId() {
        return libraryId;
    }

    public void setLibraryId(Integer libraryId) {
        this.libraryId = libraryId;
    }


    public boolean isBreach() {
        return breach;
    }

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

    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;
    }

    public boolean isManualAbsent() {
        return manualAbsent;
    }

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

    public String getPaperType() {
        return paperType;
    }

    public void setPaperType(String paperType) {
        this.paperType = paperType;
    }

    public String getCollege() {
        return college;
    }

    public void setCollege(String college) {
        this.college = college;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getTeacher() {
        return teacher;
    }

    public void setTeacher(String teacher) {
        this.teacher = teacher;
    }

    public List<ExamQuestion> getSubjectiveQuestionList() {
        return subjectiveQuestionList;
    }

    public void setSubjectiveQuestionList(List<ExamQuestion> subjectiveQuestionList) {
        this.subjectiveQuestionList = subjectiveQuestionList;
    }

    public List<ExamQuestion> getObjectiveQuestionList() {
        return objectiveQuestionList;
    }

    public void setObjectiveQuestionList(List<ExamQuestion> objectiveQuestionList) {
        this.objectiveQuestionList = objectiveQuestionList;
    }


    public SubjectiveStatus getSubjectiveStatus() {
        return subjectiveStatus;
    }

    public void setSubjectiveStatus(String subjectiveStatusStr) {
        this.subjectiveStatus = SubjectiveStatus.valueOf(subjectiveStatusStr);
    }
    
    public void copySubjectiveStatus(SubjectiveStatus sta) {
        this.subjectiveStatus = sta;
    }
    

    public String getSecretNumber() {
        return secretNumber;
    }


    public Date getInspectTime() {
        return inspectTime;
    }

    public void setInspectTime(Date inspectTime) {
        this.inspectTime = inspectTime;
    }

    public void setSecretNumber(String secretNumber) {
        this.secretNumber = secretNumber;
    }

    public String getExamName() {
        return examName;
    }

    public void setExamName(String examName) {
        this.examName = examName;
    }

    public Integer getInspectorId() {
        return inspectorId;
    }

    public void setInspectorId(Integer inspectorId) {
        this.inspectorId = inspectorId;
    }


    public String getProblemUserName() {
        return problemUserName;
    }

    public void setProblemUserName(String problemUserName) {
        this.problemUserName = problemUserName;
    }

    public String getProblemRestTime() {
        return problemRestTime;
    }

    public void setProblemRestTime(String problemRestTime) {
        this.problemRestTime = problemRestTime;
    }

    public Integer getCardNumber() {
        return cardNumber;
    }

    public void setCardNumber(Integer cardNumber) {
        this.cardNumber = cardNumber;
    }


    public Map<String, InspectHistory> getInspectHistoryMap() {
		return inspectHistoryMap;
	}

	public void setInspectHistoryMap(Map<String, InspectHistory> inspectHistoryMap) {
		this.inspectHistoryMap = inspectHistoryMap;
	}

	public Integer getInspectCount() {
        return inspectCount;
    }

    public void setInspectCount(Integer inspectCount) {
        this.inspectCount = inspectCount;
    }

	public Integer getScoreVerifyUser() {
		return scoreVerifyUser;
	}

	public void setScoreVerifyUser(Integer scoreVerifyUser) {
		this.scoreVerifyUser = scoreVerifyUser;
	}

	public Date getScoreVerifyTime() {
		return scoreVerifyTime;
	}

	public void setScoreVerifyTime(Date scoreVerifyTime) {
		this.scoreVerifyTime = scoreVerifyTime;
	}

	public Boolean getScoreVerifyFlagged() {
		return scoreVerifyFlagged;
	}

	public void setScoreVerifyFlagged(Boolean scoreVerifyFlagged) {
		this.scoreVerifyFlagged = scoreVerifyFlagged;
	}

	public boolean getInspected() {
		return inspected;
	}

	public void setInspected(boolean inspected) {
		this.inspected = inspected;
	}
	
	public static ExamStudentVo of(ExamStudent e) {
		ExamStudentVo vo=new ExamStudentVo();
		BeanUtils.copyProperties(e, vo);
		vo.copySubjectiveStatus(e.getSubjectiveStatus());
		return vo;
	}

	public Boolean getSelective() {
		return selective;
	}

	public void setSelective(Boolean selective) {
		this.selective = selective;
	}
	
}
