@Entity
@DiscriminatorValue("ALUNO")
public class Aluno extends Usuario {

} @Entity
public class Atividade extends DominioProfessor<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_atividade")
    @SequenceGenerator(name = "seq_atividade", sequenceName = "seq_atividade", allocationSize = 1, initialValue = 1)
    private Integer             id;

    @Column(length = 50)
    private String              descricao;

    @OneToOne
    private MaterialConfigurado materialConfigurado;

    public Integer getId() {
        return id;
    }

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

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public MaterialConfigurado getMaterialConfigurado() {
        return materialConfigurado;
    }

    public void setMaterialConfigurado(MaterialConfigurado materialConfigurado) {
        this.materialConfigurado = materialConfigurado;
    }

} @Entity
public class ConfiguracaoPagina extends Identity<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_config_pagina")
    @SequenceGenerator(name = "seq_config_pagina", sequenceName = "seq_config_pagina", allocationSize = 1, initialValue = 1)
    private Integer             id;

    @ManyToOne
    private MaterialConfigurado materialConfigurado;

    private Integer             pagina;

    private Integer             minMinutosPorPagina;

    @ManyToMany(cascade = CascadeType.ALL)
    @CollectionTable(name = "CONFIGURACAOPAGINAQUESTAO")
    @OrderBy("id")
    private List<Questao>       questoes;

    public Integer getId() {
        return id;
    }

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

    public MaterialConfigurado getMaterialConfigurado() {
        return materialConfigurado;
    }

    public void setMaterialConfigurado(MaterialConfigurado materialConfigurado) {
        this.materialConfigurado = materialConfigurado;
    }

    public Integer getPagina() {
        return pagina;
    }

    public void setPagina(Integer pagina) {
        this.pagina = pagina;
    }

    public Integer getMinMinutosPorPagina() {
        return minMinutosPorPagina;
    }

    public void setMinMinutosPorPagina(Integer minMinutosPorPagina) {
        this.minMinutosPorPagina = minMinutosPorPagina;
    }

    public List<Questao> getQuestoes() {
        return questoes;
    }

    public void setQuestoes(List<Questao> questoes) {
        this.questoes = questoes;
    }

} @Entity
public class Leitura extends Identity<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_leitura")
    @SequenceGenerator(name = "seq_leitura", sequenceName = "seq_leitura", allocationSize = 1, initialValue = 1)
    private Integer          id;

    @ManyToOne
    private TarefaEnviada tarefaEnviada;

    private Integer          pagina;

    @Temporal(TemporalType.TIMESTAMP)
    private Date             dataInicial;

    @Temporal(TemporalType.TIMESTAMP)
    private Date             dataFinal;

    public Integer getId() {
        return id;
    }

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

    public TarefaEnviada getTarefaEnviada() {
        return tarefaEnviada;
    }

    public void setTarefaEnviada(TarefaEnviada tarefaEnviada) {
        this.tarefaEnviada = tarefaEnviada;
    }

    public Integer getPagina() {
        return pagina;
    }

    public void setPagina(Integer pagina) {
        this.pagina = pagina;
    }

    public Date getDataInicial() {
        return dataInicial;
    }

    public void setDataInicial(Date dataInicial) {
        this.dataInicial = dataInicial;
    }

    public Date getDataFinal() {
        return dataFinal;
    }

    public void setDataFinal(Date dataFinal) {
        this.dataFinal = dataFinal;
    }

} @Entity
public class Material extends DominioProfessor<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_material")
    @SequenceGenerator(name = "seq_material", sequenceName = "seq_material", allocationSize = 1, initialValue = 1)
    private Integer              id;

    @Column(length = 50)
    private String               titulo;

    @Column(length = 50)
    private String               arquivoUnico;

    private Integer              numeroPaginas;

    @ElementCollection
    @MapKeyColumn(name = "pagina")
    @Column(name = "arquivoPaginado", length = 50)
    @CollectionTable(name = "MATERIALPAGINADO")
    private Map<Integer, String> arquivoPaginado;

    public Integer getId() {
        return id;
    }

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

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public Integer getNumeroPaginas() {
        return numeroPaginas;
    }

    public void setNumeroPaginas(Integer numeroPaginas) {
        this.numeroPaginas = numeroPaginas;
    }

    public String getArquivoUnico() {
        return arquivoUnico;
    }

    public void setArquivoUnico(String arquivoUnico) {
        this.arquivoUnico = arquivoUnico;
    }

    public Map<Integer, String> getArquivoPaginado() {
        return arquivoPaginado;
    }

    public void setArquivoPaginado(Map<Integer, String> arquivoPaginado) {
        this.arquivoPaginado = arquivoPaginado;
    }

} @Entity
public class MaterialConfigurado extends DominioProfessor<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_mat_configurado")
    @SequenceGenerator(name = "seq_mat_configurado", sequenceName = "seq_mat_configurado", allocationSize = 1, initialValue = 1)
    private Integer                          id;

    @ManyToOne
    private Material                         material;

    private Integer                          minMinutosPorPagina;

    @MapKey(name = "pagina")
    @OrderBy("pagina")
    @OneToMany(mappedBy = "materialConfigurado", cascade = CascadeType.ALL)
    private Map<Integer, ConfiguracaoPagina> configuracaoPaginas;

    public Integer getId() {
        return id;
    }

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

    public Material getMaterial() {
        return material;
    }

    public void setMaterial(Material material) {
        this.material = material;
    }

    public Integer getMinMinutosPorPagina() {
        return minMinutosPorPagina;
    }

    public void setMinMinutosPorPagina(Integer minMinutosPorPagina) {
        this.minMinutosPorPagina = minMinutosPorPagina;
    }

    public Map<Integer, ConfiguracaoPagina> getConfiguracaoPaginas() {
        return configuracaoPaginas;
    }

    public void setConfiguracaoPaginas(Map<Integer, ConfiguracaoPagina> configuracaoPaginas) {
        this.configuracaoPaginas = configuracaoPaginas;
    }

} @Entity
@DiscriminatorValue("PROFESSOR")
public class Professor extends Aluno {

} @Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TIPO", length = 50)
public abstract class Questao extends Identity<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_questao")
    @SequenceGenerator(name = "seq_questao", sequenceName = "seq_questao", allocationSize = 1, initialValue = 1)
    private Integer      id;

    @Column(length = 1000)
    private String       descricao;

    private Integer      peso;

    @ElementCollection
    @CollectionTable(name = "QUESTAOHABILIDADE")
    @Column(name = "habilidade", length = 50)
    private List<String> habilidades;

    public Integer getId() {
        return id;
    }

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

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public List<String> getHabilidades() {
        return habilidades;
    }

    public void setHabilidades(List<String> habilidades) {
        this.habilidades = habilidades;
    }

    public Integer getPeso() {
        return peso;
    }

    public void setPeso(Integer peso) {
        this.peso = peso;
    }

} @Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TIPO", length = 50)
public abstract class Resposta extends Identity<Integer> {

    public abstract String getAlternativaSelecionada();

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_resposta")
    @SequenceGenerator(name = "seq_resposta", sequenceName = "seq_resposta", allocationSize = 1, initialValue = 1)
    private Integer       id;

    @ManyToOne
    private TarefaEnviada tarefaEnviada;

    @ManyToOne
    private Questao       questao;

    @Enumerated(EnumType.STRING)
    @Column(length = 50)
    private Avaliacao     avaliacao;

    public Integer getId() {
        return id;
    }

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

    public Questao getQuestao() {
        return questao;
    }

    public void setQuestao(Questao questao) {
        this.questao = questao;
    }

    public Avaliacao getAvaliacao() {
        return avaliacao;
    }

    public void setAvaliacao(Avaliacao avaliacao) {
        this.avaliacao = avaliacao;
    }

    public TarefaEnviada getTarefaEnviada() {
        return tarefaEnviada;
    }

    public void setTarefaEnviada(TarefaEnviada tarefaEnviada) {
        this.tarefaEnviada = tarefaEnviada;
    }

} @Entity
@DiscriminatorValue("DISSERTATIVA")
public class RespostaDissertativa extends Resposta {

    @Column(length = 5000)
    private String reposta;

    public String getReposta() {
        return reposta;
    }

    public void setReposta(String reposta) {
        this.reposta = reposta;
    }

    @Override
    public String getAlternativaSelecionada() {
        return reposta;
    }

} @Entity
public class Tarefa extends DominioProfessor<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_tarefa")
    @SequenceGenerator(name = "seq_tarefa", sequenceName = "seq_tarefa", allocationSize = 1, initialValue = 1)
    private Integer             id;

    @Column(length = 50)
    private String              descricaoAtividade;

    private Integer             idAtividade;

    @ManyToOne
    private MaterialConfigurado materialConfigurado;

    @ManyToOne
    private Turma               turma;

    public Integer getId() {
        return id;
    }

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

    public Turma getTurma() {
        return turma;
    }

    public void setTurma(Turma turma) {
        this.turma = turma;
    }

    public String getDescricaoAtividade() {
        return descricaoAtividade;
    }

    public void setDescricaoAtividade(String descricaoAtividade) {
        this.descricaoAtividade = descricaoAtividade;
    }

    public Integer getIdAtividade() {
        return idAtividade;
    }

    public void setIdAtividade(Integer idAtividade) {
        this.idAtividade = idAtividade;
    }

    public MaterialConfigurado getMaterialConfigurado() {
        return materialConfigurado;
    }

    public void setMaterialConfigurado(MaterialConfigurado materialConfigurado) {
        this.materialConfigurado = materialConfigurado;
    }

} @Entity
public class TarefaEnviada extends DominioAluno<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_tarefa_individual")
    @SequenceGenerator(name = "seq_tarefa_individual", sequenceName = "seq_tarefa_individual", allocationSize = 1, initialValue = 1)
    private Integer               id;

    @ManyToOne
    private Tarefa                tarefa;

    @OneToMany(mappedBy = "tarefaEnviada", cascade = CascadeType.ALL)
    @MapKey(name = "pagina")
    private Map<Integer, Leitura> leituras;

    @OneToMany(mappedBy = "tarefaEnviada", cascade = CascadeType.ALL)
    @OrderBy("id")
    private List<Resposta>        respostas;

    @ElementCollection
    @Column(name = "dataAcesso")
    @CollectionTable(name = "TAREFAENVIADAACESSO")
    @Temporal(TemporalType.TIMESTAMP)
    private List<Date>            acessos;

    public Integer getId() {
        return id;
    }

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

    public Map<Integer, Leitura> getLeituras() {
        return leituras;
    }

    public void setLeituras(Map<Integer, Leitura> leituras) {
        this.leituras = leituras;
    }

    public Tarefa getTarefa() {
        return tarefa;
    }

    public void setTarefa(Tarefa tarefa) {
        this.tarefa = tarefa;
    }

    public List<Resposta> getRespostas() {
        return respostas;
    }

    public void setRespostas(List<Resposta> respostas) {
        this.respostas = respostas;
    }

    public List<Date> getAcessos() {
        return acessos;
    }

    public void setAcessos(List<Date> acessos) {
        this.acessos = acessos;
    }

    @Deprecated
    public int getPorcentagemConcluida() {
        Map<Integer, Leitura> leituras = getLeituras();
        if (leituras == null) return 0;
        int total = tarefa.getMaterialConfigurado().getMaterial().getNumeroPaginas();
        int lidas = 0;
        for (Leitura leitura : leituras.values()) {
            if (leitura != null && leitura.getDataFinal() != null) {
                lidas++;
            }
        }
        return 100 * lidas / total;
    }

    @Deprecated
    public int getUltimaPagina() {
        Map<Integer, Leitura> leituras = getLeituras();
        if (leituras == null) return 0;
        int pagina = 0;
        for (Leitura leitura : leituras.values()) {
            if (leitura != null && leitura.getDataFinal() != null && leitura.getPagina() > pagina) {
                pagina = leitura.getPagina();
            }
        }
        return pagina + 1;
    }

} @Entity
public class Turma extends Identity<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_turma")
    @SequenceGenerator(name = "seq_turma", sequenceName = "seq_turma", allocationSize = 1, initialValue = 1)
    private Integer    id;

    @Column(length = 50)
    private String     nome;

    @ManyToMany
    @CollectionTable
    private Set<Aluno> alunos;

    public Integer getId() {
        return id;
    }

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

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Set<Aluno> getAlunos() {
        return alunos;
    }

    public void setAlunos(Set<Aluno> alunos) {
        this.alunos = alunos;
    }

} public enum Avaliacao {

    INCORRETO("Incorreto"), CORRETO("Correto");

    private final String descricao;

    private Avaliacao(String desc) {
        this.descricao = desc;
    }

    public String getDescricao() {
        return descricao;
    }

} public class AvaliacaoQuestionarioModel {

    public static class RespostaModel {

        private Integer   id;
        private String    questao;
        private String    resposta;
        private Avaliacao avaliacao;

        public String getQuestao() {
            return questao;
        }

        public void setQuestao(String questao) {
            this.questao = questao;
        }

        public String getResposta() {
            return resposta;
        }

        public void setResposta(String resposta) {
            this.resposta = resposta;
        }

        public Avaliacao getAvaliacao() {
            return avaliacao;
        }

        public void setAvaliacao(Avaliacao avaliacao) {
            this.avaliacao = avaliacao;
        }

        public Integer getId() {
            return id;
        }

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

    }

    private Integer             idTarefaEnviada;
    private Integer             idTarefa;
    private String              atividade;
    private String              turma;
    private String              material;
    private String              aluno;
    private List<RespostaModel> respostas;

    public Integer getIdTarefaEnviada() {
        return idTarefaEnviada;
    }

    public void setIdTarefaEnviada(Integer idTarefaEnviada) {
        this.idTarefaEnviada = idTarefaEnviada;
    }

    public String getAtividade() {
        return atividade;
    }

    public void setAtividade(String atividade) {
        this.atividade = atividade;
    }

    public String getTurma() {
        return turma;
    }

    public void setTurma(String turma) {
        this.turma = turma;
    }

    public String getMaterial() {
        return material;
    }

    public void setMaterial(String material) {
        this.material = material;
    }

    public String getAluno() {
        return aluno;
    }

    public void setAluno(String aluno) {
        this.aluno = aluno;
    }

    public List<RespostaModel> getRespostas() {
        return respostas;
    }

    public void setRespostas(List<RespostaModel> respostas) {
        this.respostas = respostas;
    }

    public Integer getIdTarefa() {
        return idTarefa;
    }

    public void setIdTarefa(Integer idTarefa) {
        this.idTarefa = idTarefa;
    }

} public static class RespostaModel {

    private Integer   id;
    private String    questao;
    private String    resposta;
    private Avaliacao avaliacao;

    public String getQuestao() {
        return questao;
    }

    public void setQuestao(String questao) {
        this.questao = questao;
    }

    public String getResposta() {
        return resposta;
    }

    public void setResposta(String resposta) {
        this.resposta = resposta;
    }

    public Avaliacao getAvaliacao() {
        return avaliacao;
    }

    public void setAvaliacao(Avaliacao avaliacao) {
        this.avaliacao = avaliacao;
    }

    public Integer getId() {
        return id;
    }

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

} public class DesempenhoAlunoModel {

	Integer pontos = 0;
	Integer erros = 0;
	Integer acertos = 0;
	Integer porcentagemConcluida = 0;
	Integer quantidadePaginas = 0;
	List<Date> leiturasConcluidas;
	public Integer getPorcentagemConcluida() {
		return porcentagemConcluida;
	}
	public void setPorcentagemConcluida(Integer porcentagemConcluida) {
		this.porcentagemConcluida = porcentagemConcluida;
	}
	public Integer getQuantidadePaginas() {
		return quantidadePaginas;
	}
	public void setQuantidadePaginas(Integer quantidadePaginas) {
		this.quantidadePaginas = quantidadePaginas;
	}
	public List<Date> getLeiturasConcluidas() {
		return leiturasConcluidas;
	}
	public void setLeiturasConcluidas(List<Date> leiturasConcluidas) {
		this.leiturasConcluidas = leiturasConcluidas;
	}
	public Integer getPontos() {
		return pontos;
	}
	public void setPontos(Integer pontos) {
		this.pontos = pontos;
	}
	public Integer getErros() {
		return erros;
	}
	public void setErros(Integer erros) {
		this.erros = erros;
	}
	public Integer getAcertos() {
		return acertos;
	}
	public void setAcertos(Integer acertos) {
		this.acertos = acertos;
	}
	
} public class DetalharLeituraAlunoModel {

	private Aluno aluno;
	private List<Leitura> leituras;
	private Atividade atividade;
	private Tarefa tarefa;
	private Integer quantidadePaginas;
	private Integer melhorDesempenho;
	private Integer desempenhoMedio;
	private Integer desempenhoAluno;
	private Map<Date, Map<Long, Double>> dadosGrafico;
	private Map<Date, Map<Long, Long>> dadosGraficoPorDia;
	private DesempenhoAlunoModel melhorPontuacao;
	private DesempenhoAlunoModel mediaPontuacao;
	private DesempenhoAlunoModel alunoPontuacao;
	
	public Aluno getAluno() {
		return aluno;
	}
	public void setAluno(Aluno aluno) {
		this.aluno = aluno;
	}
	public List<Leitura> getLeituras() {
		return leituras;
	}
	public void setLeituras(List<Leitura> leituras) {
		this.leituras = leituras;
	}
	public Atividade getAtividade() {
		return atividade;
	}
	public void setAtividade(Atividade atividade) {
		this.atividade = atividade;
	}
	public Tarefa getTarefa() {
		return tarefa;
	}
	public void setTarefa(Tarefa tarefa) {
		this.tarefa = tarefa;
	}
	public Integer getMelhorDesempenho() {
		return melhorDesempenho;
	}
	public void setMelhorDesempenho(Integer melhorDesempenho) {
		this.melhorDesempenho = melhorDesempenho;
	}
	public Integer getDesempenhoMedio() {
		return desempenhoMedio;
	}
	public void setDesempenhoMedio(Integer desempenhoMedio) {
		this.desempenhoMedio = desempenhoMedio;
	}
	public Integer getDesempenhoAluno() {
		return desempenhoAluno;
	}
	public void setDesempenhoAluno(Integer desempenhoAluno) {
		this.desempenhoAluno = desempenhoAluno;
	}
	public void setQuantidadePaginas(Integer quantidadePaginas) {
		this.quantidadePaginas = quantidadePaginas;
	}
	public Integer getQuantidadePaginas() {
		return quantidadePaginas;
	}
	public void setDadosGrafico(Map<Date, Map<Long, Double>> dadosGrafico) {
		this.dadosGrafico = dadosGrafico;
	}
	public Map<Date, Map<Long, Double>> getDadosGrafico() {
		return dadosGrafico;
	}
	public void setDadosGraficoPorDia(
			Map<Date, Map<Long, Long>> dadosGraficoPorDia) {
		this.dadosGraficoPorDia = dadosGraficoPorDia;
	}
	public Map<Date, Map<Long, Long>> getDadosGraficoPorDia() {
		return dadosGraficoPorDia;
	}
	public DesempenhoAlunoModel getMelhorPontuacao() {
		return melhorPontuacao;
	}
	public void setMelhorPontuacao(DesempenhoAlunoModel melhorPontuacao) {
		this.melhorPontuacao = melhorPontuacao;
	}
	public DesempenhoAlunoModel getMediaPontuacao() {
		return mediaPontuacao;
	}
	public void setMediaPontuacao(DesempenhoAlunoModel mediaPontuacao) {
		this.mediaPontuacao = mediaPontuacao;
	}
	public DesempenhoAlunoModel getAlunoPontuacao() {
		return alunoPontuacao;
	}
	public void setAlunoPontuacao(DesempenhoAlunoModel alunoPontuacao) {
		this.alunoPontuacao = alunoPontuacao;
	}
	
} public class InformarAlunosModel {

    @NotEmpty
    @Size(max = 50)
    private String  nomeAtividade;

    @NotEmpty
    @Size(max = 50)
    private String  turma;

    @NotEmpty
    @Size(max = 999)
    @Pattern(regexp =
        "^([a-zA-Z0-9\\._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9]{2,}\\s*)+$*", message =
        "E-mails devem ser algo como nome@email(.com, .gov, .br, etc). Sem virgulas ou caracteres especiais.")
    private String  emails;

    @NotNull
    private Integer idMaterialConfigurado;

    public String getNomeAtividade() {
        return nomeAtividade;
    }

    public void setNomeAtividade(String nomeAtividade) {
        this.nomeAtividade = nomeAtividade;
    }

    public String getEmails() {
        return emails;
    }

    public void setEmails(String emails) {
        this.emails = emails;
    }

    public String getTurma() {
        return turma;
    }

    public void setTurma(String turma) {
        this.turma = turma;
    }

    public Integer getIdMaterialConfigurado() {
        return idMaterialConfigurado;
    }

    public void setIdMaterialConfigurado(Integer idMaterialConfigurado) {
        this.idMaterialConfigurado = idMaterialConfigurado;
    }

} public class LeituraModel {

	private Aluno aluno;
	private Integer paginasAcessiveis;
	private Integer paginaAtual;
	private Integer quantidadePaginas;
	private Leitura leitura;
	private String arquivoPagina;
	private boolean tempoMinimoUltrapassado;
	private boolean completa;
	private Integer tempoDecorrido;
	private Integer tempoMinimo;
	private Atividade atividade;
	private Tarefa tarefa;
	private Integer quantidadeQuestoes;

	public Aluno getAluno() {
		return aluno;
	}

	public void setAluno(Aluno aluno) {
		this.aluno = aluno;
	}

	public Integer getPaginasAcessiveis() {
		return paginasAcessiveis;
	}

	public void setPaginasAcessiveis(Integer paginasAcessiveis) {
		this.paginasAcessiveis = paginasAcessiveis;
	}

	public Integer getPaginaAtual() {
		return paginaAtual;
	}

	public void setPaginaAtual(Integer paginaAtual) {
		this.paginaAtual = paginaAtual;
	}

	public Leitura getLeitura() {
		return leitura;
	}

	public void setLeitura(Leitura leitura) {
		this.leitura = leitura;
	}
	
	public void setArquivoPagina(String arquivoPagina) {
		this.arquivoPagina = arquivoPagina;
	}
	
	public String getArquivoPagina() {
		return arquivoPagina;
	}
	
	public void setTempoMinimoUltrapassado(boolean tempoMinimoUltrapassado) {
		this.tempoMinimoUltrapassado = tempoMinimoUltrapassado;
	}
	
	public boolean getTempoMinimoUltrapassado() {
		return tempoMinimoUltrapassado;
	}
	
	public boolean getCompleta() {
		return completa;
	}
	
	public void setCompleta(boolean completa) {
		this.completa = completa;
	}

	public Integer getTempoDecorrido() {
		return tempoDecorrido;
	}

	public void setTempoDecorrido(Integer tempoDecorrido) {
		this.tempoDecorrido = tempoDecorrido;
	}

	public Atividade getAtividade() {
		return atividade;
	}

	public void setAtividade(Atividade atividade) {
		this.atividade = atividade;
	}

	public Tarefa getTarefa() {
		return tarefa;
	}

	public void setTarefa(Tarefa tarefa) {
		this.tarefa = tarefa;
	}
	
	public void setTempoMinimo(Integer tempoMinimo) {
		this.tempoMinimo = tempoMinimo;
	}
	
	public Integer getTempoMinimo() {
		return tempoMinimo;
	}
	
	public void setQuantidadeQuestoes(Integer quantidadeQuestoes) {
		this.quantidadeQuestoes = quantidadeQuestoes;
	}
	
	public Integer getQuantidadeQuestoes() {
		return quantidadeQuestoes;
	}
	
	public void setQuantidadePaginas(Integer quantidadePaginas) {
		this.quantidadePaginas = quantidadePaginas;
	}
	
	public Integer getQuantidadePaginas() {
		return quantidadePaginas;
	}
	
} public class QuestionarioModel {

	List<Questao> questoes;
	List<Resposta> respostas;
	
	public List<Questao> getQuestoes() {
		return questoes;
	}
	public void setQuestoes(List<Questao> questoes) {
		this.questoes = questoes;
	}
	public List<Resposta> getRespostas() {
		return respostas;
	}
	public void setRespostas(List<Resposta> respostas) {
		this.respostas = respostas;
	}
	
} public class ResponderQuestionarioModel {

	public static class ItemResposta {
		Integer idResposta;
		Integer idQuestao;
		String resposta;
		public Integer getIdResposta() {
			return idResposta;
		}
		public void setIdResposta(Integer idResposta) {
			this.idResposta = idResposta;
		}
		public Integer getIdQuestao() {
			return idQuestao;
		}
		public void setIdQuestao(Integer idQuestao) {
			this.idQuestao = idQuestao;
		}
		public String getResposta() {
			return resposta;
		}
		public void setResposta(String resposta) {
			this.resposta = resposta;
		}
		
	}
	
	List<ItemResposta> respostasDissertativas;
	Boolean enviar;
	
	public void setRespostasDissertativas(
			List<ItemResposta> respostasDissertativas) {
		this.respostasDissertativas = respostasDissertativas;
	}
	public List<ItemResposta> getRespostasDissertativas() {
		return respostasDissertativas;
	}
	public Boolean getEnviar() {
		return enviar;
	}
	public void setEnviar(Boolean enviar) {
		this.enviar = enviar;
	}
	
} public static class ItemResposta {
	Integer idResposta;
	Integer idQuestao;
	String resposta;
	public Integer getIdResposta() {
		return idResposta;
	}
	public void setIdResposta(Integer idResposta) {
		this.idResposta = idResposta;
	}
	public Integer getIdQuestao() {
		return idQuestao;
	}
	public void setIdQuestao(Integer idQuestao) {
		this.idQuestao = idQuestao;
	}
	public String getResposta() {
		return resposta;
	}
	public void setResposta(String resposta) {
		this.resposta = resposta;
	}
		
} public interface AlunoRepository extends EntityRepository<Aluno, Integer> {

    Aluno findByEmail(String email);

    @Query("select a from Aluno as a")
    List<Aluno> findAll();

} public interface AtividadeRepository extends EntityRepository<Atividade, Integer> {

} public interface MaterialConfiguradoRepository extends EntityRepository<MaterialConfigurado, Integer> {

    MaterialConfigurado findByIdAndProfessor(Integer id, Professor professor);

} public interface TarefaEnviadaRepository extends EntityRepository<TarefaEnviada, Integer> {

    @Modifying
    @Query("update TarefaEnviada te set te.aluno = ?1 where te.aluno = ?2")
    void moverTarefasConvidadoParaUsuario(Aluno usuario, Aluno convidado);
    
    List<TarefaEnviada> findByAluno(Aluno aluno);
    
    List<TarefaEnviada> findByTarefa(Tarefa tarefa);
    
    @Query("select l from Leitura l where l.tarefaEnviada.tarefa = ?1")
    List<Leitura> findLeiturasByTarefa(Tarefa tarefa);
    

} public interface TarefaRepository extends EntityRepository<Tarefa, Integer>{

} public interface TurmaRepository extends EntityRepository<Turma, Integer> {

    List<Turma> findByAlunosIn(Aluno convidado);
    
    @Query(value="select distinct t.turma from Tarefa t where t.professor = ?1 ")
    List<Turma> findByTurmaByProfessor(Professor p);

} public interface AtividadeService {

    Result<Void> enviarAtividade(InformarAlunosModel alunos, Integer idMaterialConfigurado, Professor professor);

    LeituraModel iniciarLeitura(Integer idTarefaEnviada, Integer pagina);

    LeituraModel resumoLeitura(Integer idTarefaEnviada);

    boolean avancarLeitura(Integer idTarefaEnviada, Integer pagina);

    QuestionarioModel recuperarQuestionario(Integer idTarefaEnviada, Integer pagina);

    boolean gravarQuestionario(Integer idTarefaEnviada,
        Integer pagina, ResponderQuestionarioModel respostas);

    DetalharLeituraAlunoModel getInformacoesDetalheLeitura(
        Integer idTarefaEnviada);

    List<QuestionarioModel> getInformacoesRespostas(Integer idTarefaEnviada);

    AvaliacaoQuestionarioModel buscarAvaliacaoQuestionario(Integer idTarefaEnviada);

    Result<Void> salvarAvaliacaoQuestionario(AvaliacaoQuestionarioModel avaliacao);

} public class Result<E> {

    public enum Status {
        SUCCESS, FAILURE
    }

    private final String    message;
    private final Status    status;
    private final E         value;
    private final Violation violation;

    private Result(String message, E value) {
        this.message = message;
        this.status = Status.SUCCESS;
        this.value = value;
        this.violation = null;
    }

    private Result(Violation violation, E value) {
        this.message = violation.getMessage();
        this.status = Status.FAILURE;
        this.value = value;
        this.violation = violation;
    }

    public static final <E> Result<E> success(String message) {
        return new Result<E>(message, null);
    }

    public static final <E> Result<E> success(String message, E value) {
        return new Result<E>(message, value);
    }

    public static final <E> Result<E> failure(Violation violation) {
        return new Result<E>(violation, null);
    }

    public static final <E> Result<E> failure(Violation violation, E value) {
        return new Result<E>(violation, value);
    }

    public String getMessage() {
        return message;
    }

    public boolean isSuccess() {
        return status == Status.SUCCESS;
    }

    public boolean isFailure() {
        return status == Status.FAILURE;
    }

    public boolean hasValue() {
        return Has.content(value);
    }

    public E getValue() {
        return value;
    }

    public Violation getViolation() {
        return violation;
    }

    public Status getStatus() {
        return status;
    }

    public boolean failsAt(Violation violation, Violation... violations) {
        if (this.violation == null || this.status == Status.SUCCESS) {
            return false;
        }

        if (this.violation == violation || violation.equals(this.violation)) {
            return true;
        }

        if (violations != null && violations.length > 0) {
            for (Violation v : violations) {
                if (this.violation == v || this.violation.equals(v)) {
                    return true;
                }
            }
        }

        return false;
    }

} public class UrlMapping implements ServletContextAware {

    private String url;
    private String path;
    private String contexto;

    public String getUrl() {
        return url;
    }

    @Override
    public String toString() {
        return path;
    }

    public String getPath() {
        return path;
    }

    public String getRedirectPath() {
        return "redirect:" + path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.contexto = servletContext.getContextPath();
        this.url = contexto + path;
    }

}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Named;
import org.joda.time.DateTime;
import org.joda.time.Minutes;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.springframework.transaction.annotation.Transactional;
import br.com.delogic.csa.manager.EmailManager;
import br.com.delogic.csa.manager.email.EmailAddress;
import br.com.delogic.csa.manager.email.EmailContent;
import br.com.delogic.jfunk.Has;
import br.com.delogic.leitoor.entidade.Aluno;
import br.com.delogic.leitoor.entidade.Atividade;
import br.com.delogic.leitoor.entidade.ConfiguracaoPagina;
import br.com.delogic.leitoor.entidade.Leitura;
import br.com.delogic.leitoor.entidade.Material;
import br.com.delogic.leitoor.entidade.MaterialConfigurado;
import br.com.delogic.leitoor.entidade.Professor;
import br.com.delogic.leitoor.entidade.Questao;
import br.com.delogic.leitoor.entidade.Resposta;
import br.com.delogic.leitoor.entidade.RespostaDissertativa;
import br.com.delogic.leitoor.entidade.Tarefa;
import br.com.delogic.leitoor.entidade.TarefaEnviada;
import br.com.delogic.leitoor.entidade.Turma;
import br.com.delogic.leitoor.entidade.enums.Avaliacao;
import br.com.delogic.leitoor.model.AvaliacaoQuestionarioModel;
import br.com.delogic.leitoor.model.AvaliacaoQuestionarioModel.RespostaModel;
import br.com.delogic.leitoor.model.DesempenhoAlunoModel;
import br.com.delogic.leitoor.model.DetalharLeituraAlunoModel;
import br.com.delogic.leitoor.model.InformarAlunosModel;
import br.com.delogic.leitoor.model.LeituraModel;
import br.com.delogic.leitoor.model.QuestionarioModel;
import br.com.delogic.leitoor.model.ResponderQuestionarioModel;
import br.com.delogic.leitoor.model.ResponderQuestionarioModel.ItemResposta;
import br.com.delogic.leitoor.repository.AlunoRepository;
import br.com.delogic.leitoor.repository.AtividadeRepository;
import br.com.delogic.leitoor.repository.MaterialConfiguradoRepository;
import br.com.delogic.leitoor.repository.TarefaEnviadaRepository;
import br.com.delogic.leitoor.repository.TarefaRepository;
import br.com.delogic.leitoor.repository.TurmaRepository;
import br.com.delogic.leitoor.service.AtividadeService;
import br.com.delogic.leitoor.util.Result;
import br.com.delogic.leitoor.util.csa.UrlMapping;
package br.com.delogic.leitoor.service.impl;





@Named("atividadeService")
public class AtividadeServiceImpl implements AtividadeService {

    @Inject
    private MaterialConfiguradoRepository matConfiguradoRepository;

    @Inject
    private AtividadeRepository           atividadeRepository;

    @Inject
    private AlunoRepository               alunoRepository;

    @Inject
    private TurmaRepository               turmaRepository;

    @Inject
    private TarefaRepository              tarefaRepository;

    @Inject
    private EmailManager                  emailManager;

    @Inject
    private TarefaEnviadaRepository       tarefaEnviadaRepository;

    @Inject
    @Named("urlLerTarefaEnviada")
    private UrlMapping                    urlLerTarefaEnviada;

    @Override
    @Transactional
    public Result<Void> enviarAtividade(InformarAlunosModel informarAlunos, Integer idMaterialConfigurado, Professor professor) {

        Atividade atividade = new Atividade();
        atividade.setDescricao(informarAlunos.getNomeAtividade());
        atividade.setMaterialConfigurado(matConfiguradoRepository.findById(idMaterialConfigurado));
        atividade.setProfessor(professor);

        atividadeRepository.create(atividade);

        Set<Aluno> alunos = new HashSet<Aluno>();
        String[] emails = informarAlunos.getEmails().split(" ");
        for (String email : emails) {
            Aluno aluno = alunoRepository.findByEmail(email.toLowerCase().trim());
            if (aluno == null) {
                aluno = new Aluno();
                aluno.setEmail(email.toLowerCase().trim());
                aluno.setNome(email.toLowerCase().trim());
                aluno.setConvite(gerarConvite());
                aluno.setConvidadoPor(professor);
                aluno.setAtivo(Boolean.TRUE);
                alunoRepository.create(aluno);
            } else if (!Has.content(aluno.getConvite())) {
                aluno.setConvite(gerarConvite());
                aluno.setConvidadoPor(professor);
                alunoRepository.update(aluno);
            }
            alunos.add(aluno);
        }

        Turma turma = new Turma();
        turma.setAlunos(alunos);
        turma.setNome(informarAlunos.getTurma());
        turmaRepository.create(turma);

        Tarefa tarefa = new Tarefa();