#encoding: utf-8
class ExerciseController < ApplicationController
  layout "base_courses"

  # before_filter :check_authentication, :except => []
  before_filter :find_exercise_and_course, :only => [:create_exercise_question, :edit, :update, :show, :destroy,:statistics_result,
                                                     :commit_exercise, :commit_answer,:publish_exercise, :publish_notice, :end_notice, :end_exercise, :republish_exercise,
                                                     :student_exercise_list, :update_question_num, :cancel_publish,
                                                     :send_to_course, :get_student_uncomplete_question, :edit_question_score, :setting, :set_public,
                                                     :ex_setting, :add_to_exercise_bank, :choose_shixuns, :shixun_question, :back_to_answer, :export_blank_exercise, :export_student_result,
                                                     :choose_student, :redo_exercise, :cancel_commit_confirm, :cancel_commit]
  before_filter :find_course, :only => [:index,:new,:create]
  before_filter :teacher_of_course, :only => [:new, :create, :edit, :update, :destroy, :create_exercise_question, :publish_exercise, :publish_notice, :end_exercise, :cancel_publish,
                                              :update_question_num, :send_to_course, :edit_question_score, :set_public, :ex_setting, :export_blank_exercise, :export_student_result]
  before_filter :require_login, :only => [:student_exercise_list, :show]
  include ExerciseHelper
  include ApplicationHelper
  if RUBY_PLATFORM =~ /linux/
    require 'pdfkit'
  end

  def index
    if @course.is_public == 0 && !(User.current.member_of_course?(@course)||User.current.admin?)
      render_403
      return
    end

    @is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
    if @is_teacher
      exercises = @course.exercises.order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
    elsif User.current.member_of_course?(@course)
      member = @course.members.where(:user_id => User.current.id).first
      if member.try(:course_group_id).to_i == 0
        exercises = @course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
      else
        not_exercise_ids = @course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)")
        not_exercise_ids = not_exercise_ids.blank? ? "(-1)" : "(" + not_exercise_ids.map(&:exercise_id).join(",") + ")"
        exercises = @course.exercises.where("publish_time <= '#{Time.now}' and id not in #{not_exercise_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
      end
    else
      exercises = @course.exercises.where("publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC")
    end

    if params[:type]
      @type = params[:type]
      exercises = exercises.where(:exercise_status => params[:type])
    end
    @search = params[:search] ? params[:search].to_s.strip : ""
    if params[:search]
      exercises = exercises.where("exercise_name like '%#{@search}%'")
    end
    @exercises = paginateHelper exercises,15 #分页
    @left_nav_type = 4
    respond_to do |format|
      format.js
      format.html
    end
  end

  def show
    unless User.current.member_of_course?(@course) || User.current.admin?
      render_403
      return
    end
    # @exercise.course_messages.each do |message|
    #   if User.current.id == message.user_id && message.viewed == 0
    #     message.update_attributes(:viewed => true) if message.viewed == 0
    #   end
    # end
    @is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?

    unless @is_teacher
      @exercise_user = ExerciseUser.where("user_id=? and exercise_id=?", User.current.id, @exercise.id).first
      if @exercise_user.nil?
        @exercise_user = ExerciseUser.create(:user_id => User.current.id, :exercise_id => @exercise.id, :start_at => Time.now, :status => false, :commit_status => 0)
        # @exercise_user = ExerciseUser.where("user_id=? and exercise_id=?", User.current.id, @exercise.id).first
      elsif @exercise_user.start_at.nil?
        @exercise_user.update_attributes(:start_at => Time.now)
      end

      @can_edit_excercise = can_edit_exercise @exercise, @exercise_user
      if !@can_edit_excercise && !@exercise_user.status
        time = (@exercise_user.start_at.to_i + @exercise.time.to_i * 60) > @exercise.end_time.to_i ? @exercise.end_time : Time.at(@exercise_user.start_at.to_i + @exercise.time.to_i * 60)
        s_score = calculate_student_score(@exercise, @exercise_user.user)
        sub_score = @exercise_user.user.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.where(:question_type => 4).map(&:id)).empty? ? 0 : @exercise_user.subjective_score
        total_score = s_score + (sub_score && sub_score > 0 ? sub_score : 0)
        @exercise_user.update_attributes(:status => true, :end_at => time, :commit_status => 1, :objective_score => s_score,
                                         :subjective_score => sub_score, :score => total_score)
      end

      if @exercise_user.commit_status == 1 && @exercise.end_time > Time.now
        if @exercise.time == -1
          @cancel_commit = true
        else
          @cancel_commit = (Time.now.to_i - @exercise_user.start_at.to_i) < @exercise.time.to_i * 60
        end
      end

      #score = calculate_student_score(@exercise, User.current)
      #@exercise_user.update_attributes(:objective_score => score, :score => (score + (@exercise_user.subjective_score > 0 ? @exercise_user.subjective_score : 0)))
    else
      @exercise_user = ExerciseUser.where("user_id=? and exercise_id=?", params[:user_id], @exercise.id).first
      @can_edit_excercise = false
    end
    Rails.logger.info("###########can_edit_excercise:#{@can_edit_excercise}")
    # @percent = get_percent(@exercise,User.current)
    #@exercise_questions = @exercise.exercise_questions
    respond_to do |format|
      format.html {render :layout => 'base_edu'}
    end
    #end
  end

  def new
    # option = {
    #     :exercise_name => "",
    #     :course_id => @course.id,
    #     :exercise_status => 1,
    #     :user_id => User.current.id,
    #     :time => "",
    #     :end_time => "",
    #     :publish_time => "",
    #     :exercise_description => "",
    #     :show_result => 1
    # }
    @exercise = Exercise.new
    respond_to do |format|
      format.html{render :layout => 'base_edu'}
    end
  end

  def choose_shixuns
    search = params[:search]
    @quest_id = params[:quest_id]
    # 去掉对 当前用户所在单位 不公开的实训
    if User.current.admin?
      none_shixun_ids = [-1]
    else
      none_shixun_ids = ShixunSchool.where("school_id != #{User.current.user_extensions.try(:school_id)}").pluck(:shixun_id)
    end
    @shixuns = Shixun.where("status = 2 and id not in (#{none_shixun_ids.join(",")})").where("name like ?", "%#{search}%").select{|shixun| shixun.challenges.where(:st => 1).count == 0}
    @limit = 8
    @shixuns = paginateHelper @shixuns, @limit
    respond_to do |format|
      format.js
    end
  end

  def shixun_question
    @shixun = Shixun.find params[:shixun_exercise]
  end

  def create
    if params[:exercise]
      exercise = Exercise.new
      exercise.exercise_name = params[:exercise][:exercise_name]
      exercise.exercise_description = params[:exercise][:exercise_description]
      exercise.user_id = User.current.id
      exercise.course_id = params[:course_id]
      exercise.time = -1
      exercise.exercise_status = 1
      if exercise.save
        create_exercises_list exercise
        @exercise = exercise
        respond_to do |format|
          format.js
        end
      end
    end
  end

  def edit
    @is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?

    @ques_id = params[:ques_id] if params[:ques_id]
    respond_to do |format|
      format.html{render :layout => 'base_edu'}
    end
  end

  def update
    @exercise.exercise_name = params[:exercise][:exercise_name]
    @exercise.exercise_description = params[:exercise][:exercise_description]

    if @exercise.save
      respond_to do |format|
        format.js
      end
    else
      render_404
      end
  end

  def destroy
    @is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
    if @exercise && @exercise.destroy
      redirect_to exercise_index_path(:course_id => @course.id)
    end
  end

  def setting
    @is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
    @is_new = params[:is_new] ? true : false
    respond_to do |format|
      format.html{render :layout => 'base_edu'}
    end
  end

  def ex_setting
    if @exercise.exercise_status == 1 && @course.course_groups.count > 1
      @exercise.unified_setting = params[:unified_setting] ? true :false
    end

    if @exercise.unified_setting
      params_publish_time = params[:exercise_publish_time]
      params_end_time = params[:exercise_end_time]
      min_publish_time = params_publish_time
      max_end_time = params_end_time
    else
      # 获取最小发布时间和最大截止时间,赋值给homework
      params_publish_time = params[:exercise_publish_time_group]
      params_end_time = params[:exercise_end_time_group]
      min_publish_time = @exercise.publish_time ? (format_time @exercise.publish_time).to_s : ""
      max_end_time = @exercise.end_time ? (format_time @exercise.end_time).to_s : ""
      if params[:exercise_end_time_group]
        max_end_time = ""
        params[:exercise_end_time_group].each_with_index do |end_time, index|
          if end_time != ""
            if max_end_time == ""
              max_end_time = end_time
            end
            if end_time > max_end_time
              max_end_time = end_time
            end
          end
        end
      end

      if params[:exercise_publish_time_group]
        params[:exercise_publish_time_group].each_with_index do |publish_time, index|
          if publish_time != ""
            if min_publish_time == ""
              min_publish_time = publish_time
            end
            if publish_time < min_publish_time
              min_publish_time = publish_time
            end
          end
        end
      end
    end

    if params_publish_time && min_publish_time != ""
      @exercise.publish_time = min_publish_time
      @exercise.end_time = max_end_time
      if @exercise.publish_time < Time.now and @exercise.exercise_status == 1
        @exercise.exercise_status = 2

        create_exercise_user = 1
        if @exercise.course_acts.size == 0
          @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id,:course_id => @exercise.course_id)
        end
      end
    elsif params_publish_time && min_publish_time == ""
      @exercise.exercise_status = 2
      create_exercise_user = 1
      @exercise.publish_time = Time.now
      @exercise.end_time = Time.at(((1.month.since.to_i)/3600.0).ceil * 3600)

      if @exercise.course_acts.size == 0
        @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id,:course_id => @exercise.course_id)
      end
    else
      @exercise.end_time = max_end_time if params_end_time
    end

    # 不统一设置且分班数大于一则更新分组设置
    if !@exercise.unified_setting && @course.course_groups.count > 1
      @course.course_groups.each_with_index do |group, index|
        exercise_group_setting = @exercise.exercise_group_settings.where(:course_group_id => group.id).first
        unless exercise_group_setting
          exercise_group_setting = ExerciseGroupSetting.create(:exercise_id => @exercise.id, :course_group_id => group.id, :course_id => @course.id)
        end
      end
      group_id = []
      @exercise.exercise_group_settings.where("publish_time is null or publish_time > '#{Time.now}'").joins(:course_group).reorder("CONVERT(course_groups.name USING gbk) COLLATE gbk_chinese_ci ASC").each_with_index do |setting, index|
        if params[:exercise_publish_time_group] && min_publish_time != ""
          if params[:exercise_publish_time_group][index] && params[:exercise_publish_time_group][index] != ""
            setting.update_column(:publish_time, params[:exercise_publish_time_group][index])
          end
        elsif params[:exercise_publish_time_group] && min_publish_time == ""
          setting.update_column(:publish_time, Time.now)
          group_id << setting.course_group_id
        end
      end

      @exercise.exercise_group_settings.joins(:course_group).reorder("CONVERT(course_groups.name USING gbk) COLLATE gbk_chinese_ci ASC").each_with_index do |setting, index|
        if params[:exercise_end_time_group] && max_end_time != ""
          if params[:exercise_end_time_group][index] && params[:exercise_end_time_group][index] != ""
            setting.update_column(:end_time, params[:exercise_end_time_group][index])
          end
        elsif params[:exercise_end_time_group] && max_end_time == ""
          setting.update_column(:end_time, Time.at(((1.month.since.to_i)/3600.0).ceil * 3600))
        end
      end
      # 统一设置则删除分组设置
    elsif @exercise.unified_setting
      @exercise.exercise_group_settings.destroy_all
    end

    if @exercise.end_time <= Time.now && @exercise.exercise_status < 3
      @exercise.exercise_status = 3
      @exercise.exercise_users.each do |exercise_user|
        if exercise_user.commit_status == 0 && !exercise_user.start_at.nil?
          s_score = calculate_student_score(@exercise, exercise_user.user)
          sub_score = exercise_user.user.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.where(:question_type => 4).map(&:id)).empty? ? 0 : exercise_user.subjective_score
          total_score = s_score + (sub_score && sub_score > 0 ? sub_score : 0)
          exercise_user.update_attributes(:commit_status => 1, :end_at => params[:exercise_end_time], :status => true, :objective_score => s_score,
                                           :subjective_score => sub_score, :score => total_score)
        end
      end
    elsif @exercise.end_time > Time.now && @exercise.exercise_status == 3
      @exercise.exercise_status = 2
    end
    @exercise.time = (params[:time].strip == "" ? -1 : params[:time]) if params[:time]
    @exercise.question_random = params[:question_random] ? 1 : 0
    @exercise.choice_random = params[:choice_random] ? 1 : 0
    @exercise.score_open = params[:score_open] ? 1 : 0
    @exercise.answer_open = params[:answer_open] ? 1 : 0
    @exercise.show_statistic = params[:show_statistic] ? 1 : 0
    if @exercise.save
      if create_exercise_user.present?
        if group_id.present? && group_id.size != 0
          if group_id.size == @course.course_groups.count
            create_exercises_tiding @exercise, @course.student
          else
            members = @course.members.where(:course_group_id => group_id)
            create_exercises_tiding @exercise, members
          end
        else
          create_exercises_tiding @exercise, @course.student
        end
      end

      redirect_to student_exercise_list_exercise_path(@exercise)
    end
  end

  def set_public
    if User.current.admin? || User.current.allowed_to?(:as_teacher, @course)
      @exercise.update_attributes(:is_public => true)
    end
  end

  # 统计结果
  def statistics_result
    exercise_questions = @exercise.exercise_questions
    @user_ids = @exercise.exercise_users.where(:commit_status => 1).map(&:user_id)
    @user_ids_str = @user_ids.length == 0 ? "(-1)" : "("+@user_ids.join(",")+")"
    @exercise_questions = paginateHelper exercise_questions, 10
    respond_to do |format|
      format.js
    end
  end

  # 添加题目
  # question_type 1:单选 2:多选 3:填空题
  def create_exercise_question
    question_title = params[:question_title].nil? || params[:question_title].empty? ? l(:label_enter_single_title) : params[:question_title]
    option = {
        :question_title => question_title,
        :question_type => params[:question_type] || 1,
        :question_number => @exercise.exercise_questions.count + 1,
        :question_score => params[:question_type] == '5' ? 0 : params[:question_score],
        :shixun_name => params[:question_type] == '5' ? params[:shixun_name] : nil,
        :shixun_id => params[:shixun]
    }
    @exercise_questions = @exercise.exercise_questions.new option
    # params[:question_answer] 题目选项
    if params[:question_answer]
      for i in 1..params[:question_answer].count
        answer = (params[:question_answer].values[i-1].nil? || params[:question_answer].values[i-1].empty?) ? l(:label_new_answer) : params[:question_answer].values[i-1]
        question_option = {
            :choice_position => i,
            :choice_text => answer.strip
        }
        @exercise_questions.exercise_choices.new question_option
      end
    end
    # 如果是插入的话,那么从插入的这个id以后的question_num都将要+1
    if params[:quest_id] != "0"
      @is_insert = true
      insert_que = ExerciseQuestion.find params[:quest_id]
      if insert_que
        @exercise.exercise_questions.where("question_number>?",insert_que.question_number).update_all("question_number = question_number + 1")
        @exercise_questions.question_number = insert_que.question_number + 1
      end
    end
    if @exercise_questions.save
      # params[:exercise_choice] 标准答案参数
      # 问答题标准答案有三个,单独处理
      if @exercise_questions.question_type == 5
        shixun = Shixun.find params[:shixun]
        question_score = 0
        shixun.challenges.each_with_index do |challenge, index|
          ex_shixun_challenge = ExerciseShixunChallenge.new(:challenge_id => challenge.id, :shixun_id => shixun.id, :exercise_question_id => @exercise_questions.id,
                                                            :question_score => params[:question_score][index], :position => index + 1)
          ex_shixun_challenge.save
          question_score += ex_shixun_challenge.question_score
        end
        @exercise_questions.update_attributes(:question_score => question_score)
      elsif @exercise_questions.question_type == 3
        for i in 1..params[:exercise_choice].count
          standart_answer = ExerciseStandardAnswer.new
          standart_answer.exercise_question_id =  @exercise_questions.id
          standart_answer.answer_text = params[:exercise_choice].values[i-1].strip
          standart_answer.save
        end
      elsif @exercise_questions.question_type == 4
        unless params[:exercise_choice] == ""
          standart_answer = ExerciseStandardAnswer.new
          standart_answer.exercise_question_id =  @exercise_questions.id
          standart_answer.answer_text = params[:exercise_choice].strip
          standart_answer.save
        end
      else
        standart_answer = ExerciseStandardAnswer.new
        standart_answer.exercise_question_id =  @exercise_questions.id
        if  @exercise_questions.question_type == 1
          standart_answer.exercise_choice_id = sigle_selection_standard_answer(params[:exercise_choice])
        elsif @exercise_questions.question_type == 2
          standart_answer.exercise_choice_id = multiselect_standard_answer(params[:exercise_choice])
        end
        standart_answer.save
      end
      redirect_to edit_exercise_path(@exercise, :ques_id => @exercise_questions.id)
=begin
      respond_to do |format|
        format.js
      end
=end
    end

  end

  # 修改题目
  # params[:exercise_question]  The id of exercise_question
  # params[:question_answer]  eg:A、B、C选项
  def update_exercise_question
    @exercise_question = ExerciseQuestion.find params[:exercise_question]
    @exercise_question.question_title = params[:question_title].nil? || params[:question_title].empty? ? l(:label_enter_single_title) : params[:question_title]
    @exercise_question.question_score = params[:question_score] if @exercise_question.question_type != 5
    # 处理选项:如果选了某个选项,那么则要删除之前的选项
    if params[:question_answer]
      @exercise_question.exercise_choices.each do |answer|
        answer.destroy unless params[:question_answer].keys.include? answer.id.to_s
      end
      for i in 1..params[:question_answer].count
        question = @exercise_question.exercise_choices.find_by_id params[:question_answer].keys[i-1]
        answer = (params[:question_answer].values[i-1].nil? || params[:question_answer].values[i-1].empty?) ? l(:label_new_answer) : params[:question_answer].values[i-1]
        if question
          question.choice_position = i
          question.choice_text = answer
          question.save
        else
          question_option = {
              :choice_position => i,
              :choice_text => answer
          }
          @exercise_question.exercise_choices.new question_option
        end
      end
    end
    # 更新标准答案
    if params[:exercise_choice]
      if @exercise_question.question_type == 3
        # 删除不合理的选项
        @exercise_question.exercise_standard_answers.each do |answer|
          answer.destroy unless params[:exercise_choice].keys.include? answer.id.to_s
        end
        for i in 1..params[:exercise_choice].count
          # 找到对应的标准答案
          question_standart = @exercise_question.exercise_standard_answers.find_by_id params[:exercise_choice].keys[i-1]
          # 标准答案值
          answer_standart = (params[:exercise_choice].values[i-1].nil? || params[:exercise_choice].values[i-1].empty?) ? l(:label_new_answer) : params[:exercise_choice].values[i-1]
          if question_standart
            question_standart.answer_text = answer_standart
            question_standart.save
          else
            standart_answer_option = {
                :answer_text => answer_standart
            }
            @exercise_question.exercise_standard_answers.new standart_answer_option
          end
        end
      elsif @exercise_question.question_type == 4
        answer_standart = @exercise_question.exercise_standard_answers.empty? ? nil : @exercise_question.exercise_standard_answers.first
        if params[:exercise_choice] == "" && !answer_standart.nil?
          answer_standart.destroy
        elsif params[:exercise_choice] != "" && !answer_standart.nil?
          answer_standart.answer_text = params[:exercise_choice]
          answer_standart.save
        elsif params[:exercise_choice] != "" && answer_standart.nil?
          standart_answer_option = {
              :answer_text => params[:exercise_choice]
          }
          @exercise_question.exercise_standard_answers.new standart_answer_option
        end
      else
        answer_standart = @exercise_question.exercise_standard_answers.first
        answer_standart.exercise_choice_id = @exercise_question.question_type == 1 ? sigle_selection_standard_answer(params[:exercise_choice]) : multiselect_standard_answer(params[:exercise_choice])
        answer_standart.save
      end
    end
    if @exercise_question.question_type == 5
      @exercise_question.shixun_name = params[:shixun_name].strip if !params[:shixun_name].blank?
      question_score = 0
      @exercise_question.exercise_shixun_challenges.each_with_index do |challenge, index|
        challenge.question_score = params[:question_score][index]
        challenge.save
        question_score += challenge.question_score
      end
      @exercise_question.question_score = question_score
    end
    @exercise_question.save
    @exercise = @exercise_question.exercise
    redirect_to edit_exercise_path(@exercise, :ques_id => @exercise_question.id)
=begin
    respond_to do |format|
      format.js
    end
=end
  end

  # 删除题目
  def delete_exercise_question
    @exercise_question = ExerciseQuestion.find params[:exercise_question]
    @exercise = @exercise_question.exercise

    @exercise.exercise_questions.where("question_number>?",params[:quest_num].to_i).update_all("question_number = question_number - 1")
    # if @exercise_question.question_type == 1
    #   ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 1).update_all(" question_number = question_number - 1")
    #   #@exercise.exercise_questions.where("question_number > #{params[:quest_num].to_i} and question_type == 1").update_all(" question_number = question_number + 1")
    # elsif @exercise_question.question_type == 2
    #   ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 2).update_all(" question_number = question_number - 1")
    # elsif @exercise_question.question_type == 3
    #   ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 3).update_all(" question_number = question_number - 1")
    # else
    #   ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 4).update_all(" question_number = question_number - 1")
    # end
    # @exercise_question_num = params[:quest_num].to_i
    # @exercise_questions.question_number = params[:quest_num].to_i - 1
    #
    # exercise_questions = @exercise.exercise_questions.where("question_number > #{@exercise_question.question_number}")
    # exercise_questions.each do |question|
    #   question.question_number -= 1
    #   question.save
    # end
    if @exercise_question && @exercise_question.destroy
      respond_to do |format|
        format.js
      end
    end
  end

  #题目上移/下移
  def update_question_num
    @exercise_question = ExerciseQuestion.find params[:ques_id]
    exercise_questions = @exercise.exercise_questions
    if @exercise_question
      if params[:opr] == 'up' && @exercise_question.question_number > 1
        @before_que = exercise_questions.where("question_number = #{@exercise_question.question_number - 1}").first
        if @before_que && @exercise_question.update_attribute('question_number', @exercise_question.question_number - 1)
          @before_que.update_attribute('question_number', @before_que.question_number + 1)
        end
      elsif params[:opr] == 'down' && @exercise_question.question_number < exercise_questions.count
        @after_que = exercise_questions.where("question_number = #{@exercise_question.question_number + 1}").first
        if @after_que && @exercise_question.update_attribute('question_number', @exercise_question.question_number + 1)
          @after_que.update_attribute('question_number', @after_que.question_number - 1)
        end
      end
      respond_to do |format|
        format.js
      end
    end
  end

  # 发送试卷
  def send_to_course
    params[:course_ids].each do |course|
      option = {
          :exercise_name => @exercise.exercise_name,
          :exercise_status => 1,
          :user_id => User.current.id,
          :show_result => 1,
          :course_id => course.to_i,
          :time => @exercise.time,
          :exercise_description => @exercise.exercise_description
      }
      exercise = Exercise.create option

      @exercise.exercise_questions.each do |q|
        option = {
            :question_title => q[:question_title],
            :question_type => q[:question_type] || 1,
            :question_number => q[:question_number],
            :question_score => q[:question_score]
        }
        exercise_question = exercise.exercise_questions.new option

        for i in 1..q.exercise_choices.count
          choice_option = {
              :choice_position => i,
              :choice_text => q.exercise_choices[i-1][:choice_text]
          }
          exercise_question.exercise_choices.new choice_option
        end

        for i in 1..q.exercise_standard_answers.count
          standard_answer_option = {
              :exercise_choice_id => q.exercise_standard_answers[i-1][:exercise_choice_id],
              :answer_text => q.exercise_standard_answers[i-1][:answer_text]
          }
          exercise_question.exercise_standard_answers.new standard_answer_option
        end
      end
      exercise.save
    end
    respond_to do |format|
      format.js
    end
  end

  # 搜索当前用户任教的班级(不包含该试卷所在的班级)
  def search_courses
    @user = User.current
    if !params[:name].nil?
      search = "%#{params[:name].to_s.strip.downcase}%"
      @courses = @user.courses.not_deleted.where("courses.id != #{params[:course].to_i} and (#{Course.table_name}.id = #{params[:search].to_i } or #{Course.table_name}.name like :p)",:p=>search).reorder("created_at desc").select {|course| @user.allowed_to?(:as_teacher,course)}
    else
      @courses = @user.courses.not_deleted.where("courses.id != #{params[:course].to_i}").reorder("created_at desc").select {|course| @user.allowed_to?(:as_teacher,course)}
    end
    respond_to do |format|
      format.js
    end
  end

  def cancel_publish
    ActiveRecord::Base.transaction do
      @exercise.exercise_users.destroy_all
      ExerciseAnswer.where(:exercise_question_id => @exercise.exercise_questions.pluck(:id)).destroy_all
      ExerciseShixunAnswer.where(:exercise_question_id => @exercise.exercise_questions.pluck(:id)).destroy_all
      @exercise.update_attributes(:exercise_status => 1, :publish_time => nil, :end_time => nil, :unified_setting => 1)
      @exercise.exercise_group_settings.destroy_all
      @exercise.course_acts.destroy_all
      @exercise.tidings.destroy_all
      create_exercises_list @exercise
    end
    redirect_to student_exercise_list_exercise_path(@exercise)
  end

  def publish_notice
    if @exercise.publish_time
      @status = 1
    else
      @status = 0
    end
    if @course.course_groups.count > 1
      if @exercise.unified_setting
        @groups = @course.course_groups
      else
        @groups = @course.course_groups.where(:id => @exercise.exercise_group_settings.where("publish_time is null or publish_time > '#{Time.now}'").map(&:course_group_id))
      end
      @all_groups = @groups
      @groups = paginateHelper @groups, 5
    end
  end

  # 发布试卷
  def publish_exercise
    if @exercise.exercise_status == 1
      if params[:group_ids]
        if @course.course_groups.where(:id => params[:group_ids].split(",")).count == @course.course_groups.count
          @exercise.exercise_group_settings.destroy_all
          @exercise.update_attribute("unified_setting", true)
          # 发消息
          create_exercises_tiding @exercise, @course.student
        else
          @exercise.update_attribute("unified_setting", false)
          @course.course_groups.each do |group|
            exercise_group_setting = @exercise.exercise_group_settings.where(:course_group_id => group.id).first
            unless exercise_group_setting
              ExerciseGroupSetting.create(:exercise_id => @exercise.id, :course_group_id => group.id, :course_id => @course.id, :publish_time => @exercise.publish_time, :end_time => @exercise.end_time)
            end
          end
          @exercise.exercise_group_settings.where(:course_group_id => params[:group_ids].split(",")).update_all(:publish_time => Time.now)
          @exercise.exercise_group_settings.where(:course_group_id => params[:group_ids].split(","), :end_time => nil).update_all(:end_time => Time.at(((1.month.since.to_i)/3600.0).ceil * 3600))
          # 发消息
          members = @course.members.where(:course_group_id => params[:group_ids].split(","))
          create_exercises_tiding @exercise, members
        end
      else
        @exercise.exercise_group_settings.destroy_all
        # 发消息
        create_exercises_tiding @exercise, @course.student
      end

      @exercise.exercise_status = 2
      @exercise.publish_time = Time.now

      if @exercise.end_time.nil?
        @exercise.end_time = Time.at(((1.month.since.to_i)/3600.0).ceil * 3600)
      elsif ExerciseGroupSetting.where("exercise_id = #{@exercise.id} and end_time is not null").count > 0
        @exercise.update_attribute("end_time", ExerciseGroupSetting.where("exercise_id = #{@exercise.id} and end_time is not null").map(&:end_time).max)
      end
      if @exercise.save
        # create_exercises_list @exercise
        if @exercise.course_acts.size == 0
          @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id,:course_id => @exercise.course_id)
        end
      end
    else
      @exercise.exercise_group_settings.where(:course_group_id => params[:group_ids].split(",")).update_all(:publish_time => Time.now)
      @exercise.exercise_group_settings.where(:course_group_id => params[:group_ids].split(","), :end_time => nil).update_all(:end_time => Time.at(((1.month.since.to_i)/3600.0).ceil * 3600))
      if ExerciseGroupSetting.where("exercise_id = #{@exercise.id} and end_time is not null").count > 0
        @exercise.update_attribute("end_time", ExerciseGroupSetting.where("exercise_id = #{@exercise.id} and end_time is not null").map(&:end_time).max)
      end
      members = @course.members.where(:course_group_id => params[:group_ids].split(","))
      create_exercises_tiding @exercise, members
    end
    if @exercise.end_time > Time.now && @exercise.exercise_status > 2
      @exercise.update_attribute("exercise_status", 2)
    end
    redirect_to student_exercise_list_exercise_path(@exercise)
  end

  def end_notice
    if @course.course_groups.count > 1
      unless @exercise.unified_setting
        @groups = @course.course_groups.where(:id => @exercise.exercise_group_settings.where("publish_time < '#{Time.now}' and end_time > '#{Time.now}'").map(&:course_group_id))
        @all_groups = @groups
        @groups = paginateHelper @groups, 5
      end
    end
  end

  def end_exercise
    time = Time.now
    exercise_users = @exercise.exercise_users.where("0=1")
    #if @exercise.exercise_status == 2 && @exercise.end_time > Time.now
      if params[:group_ids]
        # @exercise.exercise_group_settings.where(:course_group_id => params[:group_id]).where("publish_time > '#{Time.now}' or publish_time is null").update_all(:publish_time => time)
        @exercise.exercise_group_settings.where(:course_group_id => params[:group_ids].split(",")).update_all(:end_time => time)
        exercise_users = @exercise.exercise_users.where(:user_id => @course.members.where(:course_group_id => params[:group_ids].split(",")).map(&:user_id))
        @exercise.update_attribute("end_time", ExerciseGroupSetting.where("exercise_id = #{@exercise.id} and end_time is not null").map(&:end_time).max)
        if @exercise.end_time > Time.now && @exercise.exercise_status > 2
          @exercise.update_attribute("exercise_status", 2)
        elsif @exercise.end_time <= Time.now && @exercise.exercise_status == 2
          @exercise.update_attribute("exercise_status", 3)
        end
      elsif @exercise.unified_setting
        exercise_users = @exercise.exercise_users
        @exercise.update_attributes(:exercise_status => 3, :end_time => time)
      end

      exercise_users.each do |exercise_user|
        if exercise_user.commit_status == 0 && !exercise_user.start_at.nil?
          time = (exercise_user.start_at.to_i + @exercise.time.to_i * 60) > @exercise.end_time.to_i ? @exercise.end_time : Time.at(exercise_user.start_at.to_i + @exercise.time.to_i * 60)
          s_score = calculate_student_score(@exercise, exercise_user.user)
          sub_score = exercise_user.user.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.where(:question_type => 4).map(&:id)).empty? ? 0 : exercise_user.subjective_score
          exercise_user.update_attributes(:status => 1, :commit_status => 1, :end_at => time, :objective_score => s_score, :subjective_score => sub_score,
                                          :score => (s_score + (exercise_user.subjective_score && exercise_user.subjective_score > 0 ? exercise_user.subjective_score : 0)))
        end
      end
    #end
    redirect_to student_exercise_list_exercise_path(@exercise)
  end

  # 重新发布试卷
  # 重新发布的时候会删除所有的答题
  def republish_exercise
    @is_teacher = User.current.allowed_to?(:as_teacher,@course)
    @index = params[:index]
    @exercise.exercise_questions.each do |exercise_question|
      exercise_question.exercise_answers.destroy_all
    end
    @exercise.course_messages.destroy_all
    @exercise.exercise_users.destroy_all
    @exercise.exercise_status = 1
    @exercise.publish_time = nil
    @exercise.save
    respond_to do |format|
      format.js
    end
  end

  def student_exercise_list
    @order,@b_sort,@name,@group,@comment,@status = params[:order] || "end_at",params[:sort] || "desc",params[:name].to_s.strip || "",params[:ex_group], params[:ex_comment], params[:ex_status]
    @is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
    @member = @course.members.where(:user_id => User.current.id).first

    # 判断学生是否有权限查看(试卷未发布、试卷已发布但不是统一设置的未分班学生、分班设置的试卷未发布)
    if User.current.member_of_course?(@course) && !@is_teacher
      if @exercise.publish_time.nil? || @exercise.publish_time > Time.now || (!@exercise.unified_setting && (@member.course_group_id == 0 ||
          @exercise.exercise_group_settings.where("course_group_id = #{@member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)").count > 0))
        render_403
        return
      end
    end

    student_id = @course.student.blank? ? "(-1)" : "(" + @course.student.map{|student| student.student_id}.join(",") + ")"

    if @exercise.exercise_status < 2
      @exercise_users_list = @exercise.exercise_users.where("0=1")
    elsif @exercise.unified_setting
      @exercise_users_list = @exercise.exercise_users
    else
      user_ids = @course.members.where(:course_group_id => @exercise.exercise_group_settings.where("publish_time < '#{Time.now}'").pluck(:course_group_id)).map(&:user_id)
      @exercise_users_list = @exercise.exercise_users.where(:user_id => user_ids)
    end

    if @exercise.time != -1
      @exercise.exercise_users.where("start_at is not null and end_at is null").each do |exercise_user|
        member = @course.members.where(:user_id => exercise_user.user_id).first
        setting_time = exercise_group_setting @exercise, member.try(:course_group)
        if ((Time.now.to_i - exercise_user.start_at.to_i) > @exercise.time.to_i * 60) || setting_time.end_time < Time.now
          time = (exercise_user.start_at.to_i + @exercise.time.to_i * 60) > setting_time.end_time.to_i ? setting_time.end_time : Time.at(exercise_user.start_at.to_i + @exercise.time.to_i * 60)
          s_score = calculate_student_score(@exercise, exercise_user.user)
          sub_score = exercise_user.user.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.where(:question_type => 4).map(&:id)).empty? ? 0 : exercise_user.subjective_score
          total_score = s_score + (sub_score && sub_score > 0 ? sub_score : 0)
          exercise_user.update_attributes(:commit_status => 1, :end_at => time, :status => true, :objective_score => s_score,
                                          :subjective_score => sub_score, :score => total_score)
        end
      end
    end

    @exercise.exercise_users.where("commit_status = 1 and score is null").each do |exercise_user|
      s_score = calculate_student_score(@exercise, exercise_user.user)
      sub_score = exercise_user.user.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.where(:question_type => 4).map(&:id)).empty? ? 0 : exercise_user.subjective_score
      total_score = s_score + (sub_score && sub_score > 0 ? sub_score : 0)
      exercise_user.update_attributes(:objective_score => s_score, :subjective_score => sub_score, :score => total_score)
    end

    @group_teacher = @is_teacher && @member.present? && @member.teacher_course_groups.count > 0
    if @group || @group_teacher
      group_ids = @group || @member.teacher_course_groups.pluck(:course_group_id)
      group_students = @course.members.where(:course_group_id => group_ids).joins("join users on members.user_id = users.id").select{|m| m.roles.to_s.include?("Student")}

      if group_students.empty?
        student_in_group = '(-1)'
      else
        student_in_group = '(' + group_students.map{ |member| member.user_id }.join(',')  + ')'
      end
      @exercise_users_list = @exercise_users_list.where("exercise_users.user_id in #{student_in_group}")
    else
      if @is_teacher || (!@exercise_users_list.where("exercise_users.user_id = #{User.current.id} and commit_status = 1").empty? && @exercise.score_open && @exercise.end_time <= Time.now)
        @exercise_users_list = @exercise_users_list.where("exercise_users.user_id in #{student_id}")
        @show_all = true
      elsif User.current.member_of_course?(@course)
        @exercise_users_list = @exercise_users_list.where("exercise_users.user_id = ? and exercise_users.user_id in #{student_id}",User.current.id)
      else
        @exercise_users_list = []
      end
    end

    unless @comment.blank?
      if @comment.include?('0')
        @exercise_users_list = @exercise_users_list.where(:subjective_score => -1)
      else
        @exercise_users_list = @exercise_users_list.where("subjective_score != -1")
      end
    end

    unless @status.blank?
      @exercise_users_list = @exercise_users_list.where(:commit_status => @status)
    end

    if @exercise_users_list.size != 0
      if @order == "student_id"
        @exercise_users_list = @exercise_users_list.includes(:user => {:user_extensions => []}).order("user_extensions.student_id #{@b_sort}")
      else
        @exercise_users_list = @exercise_users_list.includes(:user => {:user_extensions => []}).order("#{@order} #{@b_sort}, id desc")
      end
    end

    @exercise_users_list = search_work_member @exercise_users_list, @name

    @tab = params[:tab].nil? ? 1 : params[:tab].to_i
    @score = @b_sort == "desc" ? "asc" : "desc"
    @is_new = params[:is_new] ? true : false
    @all_exercise_user_lists = @exercise_users_list
    @exercise_count = @exercise_users_list.count
    @has_commit_count = @exercise.exercise_users.where(:commit_status => 1).count
    @no_group_count = @course.members.where(:course_group_id => 0).select{|m| m.roles.to_s.include?("Student")}.count
    @limit = 50
    @is_remote = true
    @page = (params['page'] || 1).to_i
    @exercise_pages = Paginator.new @exercise_count, @limit, @page
    @offset ||= @exercise_pages.offset
    @exercise_users_list = paginateHelper @exercise_users_list, @limit

    respond_to do |format|
      format.js
      format.html{render :layout => 'base_edu'}
      format.xls {
        filename = "#{@course.teacher.show_real_name.to_s}_#{@course.name}_#{@exercise.exercise_name}#{l(:excel_exercise_list)}.xls"
        send_data(exercise_to_xls(@all_exercise_user_lists), :type => "text/excel;charset=utf-8; header=present",
                  :filename => filename_for_content_disposition(filename))
      }
    end
  end

  def export_student_result
    url = Setting.protocol + "://" + Setting.host_name + "/exercise/" + @exercise.id.to_s + "/show_student_result?pdf=1&user_id=#{params[:user_id]}"
    logger.info("-----------------#{url}")
    kit = PDFKit.new(url, :page_size => "A4")
    file_name = @exercise.exercise_name + ".pdf"
    send_data(kit.to_pdf, :filename => file_name, :type => "application/pdf;charset=utf-8")
    return
  end

  def export_blank_exercise
    url = Setting.protocol + "://" + Setting.host_name + "/exercise/" + @exercise.id.to_s + "/blank_exercise"
    # url = "https://testbdweb.trustie.net/student_work/235992/shixun_work_report"
    logger.info("-----------------#{url}")
    # url = "https://www.educoder.net"
    kit = PDFKit.new(url, :page_size => "A4")
    # kit.stylesheets << "#{Rails.root}/app/assets/assets/stylesheets/pdf.css" # 用url时就不可以用css样式了。
    # kit.to_pdf # inline PDF
    file_name = @exercise.exercise_name + ".pdf"
    #kit.to_file(file_name)
    send_data(kit.to_pdf, :filename => filename_for_content_disposition(file_name), :type => "application/pdf;charset=utf-8")
    return
  end

  def blank_exercise
    @exercise = Exercise.find params[:id]
    respond_to do |format|
      format.html {render :layout => 'pdf'}
    end
  end

  def cancel_commit_confirm
    exercise_user = @exercise.exercise_users.where(:user_id => User.current.id).first
    if exercise_user.present? && exercise_user.commit_status == 1 && @exercise.end_time > Time.now
      if @exercise.time == -1
        @end_time = @exercise.end_time.strftime("%Y-%m-%d %H:%M")
      elsif (Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60
        time = Time.at(exercise_user.start_at.to_i + @exercise.time.to_i * 60) > @exercise.end_time ? @exercise.end_time : Time.at(exercise_user.start_at.to_i + @exercise.time.to_i * 60)
        @end_time = time.strftime("%Y-%m-%d %H:%M")
      end
    end
  end

  def cancel_commit
    exercise_user = @exercise.exercise_users.where(:user_id => User.current.id).first
    if exercise_user.present? && exercise_user.commit_status == 1 && @exercise.end_time > Time.now
      if @exercise.time == -1 || (Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60
        exercise_user.update_attributes(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, :objective_score => -1, :subjective_score => -1)
        exercise_user.user.exercise_shixun_answers.where(:exercise_question_id => @exercise.exercise_questions.map(&:id)).destroy_all
        exercise_answers = exercise_user.user.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.map(&:id))
        exercise_answers.update_all(:score => -1)
        ExerciseAnswerComment.where(:exercise_question_id => @exercise.exercise_questions.map(&:id), :exercise_answer_id => exercise_answers.pluck(:id)).destroy_all
      end
    end
    redirect_to student_exercise_list_exercise_path(@exercise)
  end

  # 学生提交答卷,选中答案的过程中提交
  def commit_answer
    eq = ExerciseQuestion.find(params[:exercise_question_id])
    # 已提交过的且是限时的则不允许答题
    exercise_user = ExerciseUser.where(:exercise_id => @exercise.id, :user_id => User.current.id).first

    if (exercise_user && exercise_user.commit_status == 1) || @exercise.end_time < Time.now
      render :json => {:text => "Over"}
      return
    end
    if eq.question_type == 1
      # 单选题
      ea = ExerciseAnswer.find_by_exercise_question_id_and_user_id(params[:exercise_question_id],User.current.id)
      if ea.nil?
        # 尚未答该题,添加答案
        ea = ExerciseAnswer.new
        ea.user_id = User.current.id
        ea.exercise_question_id = params[:exercise_question_id]
      end
      #修改该题对应答案
      ea.exercise_choice_id = params[:exercise_choice_id]
      if ea.save
        # 保存成功返回成功信息及当前以答题百分比
        uncomplete_question = get_uncomplete_question(@exercise, User.current)
        if uncomplete_question.count < 1
          complete = 1;
        else
          complete = 0;
        end
        @percent = get_percent(@exercise,User.current)
        render :json => {:text => "ok" ,:complete => complete,:percent => format("%.2f" ,@percent)}
      else
        #返回失败信息
        render :json => {:text => "failure"}
      end
    elsif eq.question_type == 2
      #多选题
      ea = ExerciseAnswer.find_by_exercise_choice_id_and_user_id(params[:exercise_choice_id],User.current.id)
      if ea.nil?
        #尚未答该题,添加答案
        ea = ExerciseAnswer.new
        ea.user_id = User.current.id
        ea.exercise_question_id = params[:exercise_question_id]
        ea.exercise_choice_id = params[:exercise_choice_id]
        if ea.save
          uncomplete_question = get_uncomplete_question(@exercise, User.current)
          if uncomplete_question.count < 1
            complete = 1;
          else
            complete = 0;
          end
          is_answer = User.current.exercise_answer.where(:exercise_question_id => params[:exercise_question_id].to_i).count > 0
          @percent = get_percent(@exercise,User.current)
          render :json => {:text => "ok",:complete => complete,:percent => format("%.2f" ,@percent),:is_answer => is_answer}
        else
          render :json => {:text => "failure"}
        end
      else
        #pv不为空,则当前选项之前已被选择,再次点击则是不再选择该项,故删除该答案
        if ea.delete
          is_answer = User.current.exercise_answer.where(:exercise_question_id => params[:exercise_question_id].to_i).count > 0
          @percent = get_percent(@exercise, User.current)
          render :json => {:text => "false" ,:percent => format("%.2f" , @percent),:is_answer => is_answer}
        else
          render :json => {:text => "failure"}
        end
      end
    elsif eq.question_type == 3 || eq.question_type == 4
      #单行文本,多行文本题
      ea = ExerciseAnswer.find_by_exercise_question_id_and_user_id(params[:exercise_question_id], User.current.id)
      if ea.nil?
        # ea为空之前尚未答题,添加答案
        if params[:answer_text].nil? || params[:answer_text].blank?
          #用户提交空答案,视作不作答
          @percent = get_percent(@exercise,User.current)
          render :json => {:text => "",:percent => format("%.2f", @percent)}
        else
          #添加答案
          ea = ExerciseAnswer.new
          ea.user_id = User.current.id
          ea.exercise_question_id = params[:exercise_question_id]
          ea.answer_text = params[:answer_text]
          if ea.save
            uncomplete_question = get_uncomplete_question(@exercise, User.current)
            if uncomplete_question.count < 1
              complete = 1;
            else
              complete = 0;
            end
            @percent = get_percent(@exercise,User.current)
            render :json => {:text => ea.answer_text,:complete => complete,:percent => format("%.2f",@percent)}
          else
            render :json => {:text => "failure"}
          end
        end

      else
        # ea不为空说明用户之前已作答
        if params[:answer_text].nil? || params[:answer_text].blank?
          # 用户提交空答案,视为删除答案
          if ea.delete
            @percent = get_percent(@exercise,User.current)
            render :json => {:text => "",:percent => format("%.2f", @percent)}
          else
            render :json => {:text => "failure"}
          end
        else
          #用户修改答案
          ea.answer_text = params[:answer_text]
          if ea.save
            @percent = get_percent(@exercise,User.current)
            render :json => {:text => ea.answer_text,:percent => format("%.2f", @percent)}
          else
            render :json => {:text => "failure"}
          end
        end
      end

    else
      render :json => {:text => "failure"}
    end
  end

  # 提交问卷
  def commit_exercise
    # 老师不需要提交
    if User.current.allowed_to?(:as_teacher,@course)
      # if @exercise.publish_time.nil? || @exercise.publish_time <= Time.now
      #   @exercise.update_attributes(:exercise_status => 2)
      #   @exercise.update_attributes(:publish_time => Time.now)
      #   course = @exercise.course
      #   course.members.each do |m|
      #     @exercise.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => 2)
      #   end
      #   redirect_to exercise_url(@exercise)
      #   return
      # elsif @exercise.publish_time > Time.now
      #   redirect_to exercise_url(@exercise)
      #   return
      # end
      # redirect_to exercise_url(@exercise)
      # REDO: 提示提交成功
    else
      # 更新提交状态
      cur_exercise_user = ExerciseUser.where("user_id =? and exercise_id=?", User.current, @exercise.id).first

      # 试卷未截止且试卷未提交过才能提交
      if @exercise.exercise_status == 2 && cur_exercise_user.present? && cur_exercise_user.commit_status == 0
        #if @exercise.time && @exercise.time != -1
        score = calculate_student_score(@exercise, User.current)
        sub_score = User.current.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.where(:question_type => 4).map(&:id)).empty? ? 0 : cur_exercise_user.subjective_score
        total_score = score + (sub_score && sub_score > 0 ? sub_score : 0)
        cur_exercise_user.update_attributes(:status => 1, :commit_status => 1, :end_at => Time.now, :objective_score => score,
                                        :subjective_score => sub_score, :score => total_score)

        # 提交后给老师和助教发消息
        tid_str = ""
        member = @course.members.where(:user_id => User.current.id).first
        teachers = tiding_teachers @course, member
        teachers.find_each do |mem|
          tid_str += "," if tid_str != ""
          tid_str += "(#{mem.user_id}, #{User.current.id}, #{@exercise.id}, 'Exercise', #{@exercise.id}, 'CommitExercise', #{@course.id}, 'Course', 0, 'Exercise', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
        end
        tid_sql = "insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values" + tid_str
        ActiveRecord::Base.connection.execute tid_sql
      end
      #end
      # 答题过程中需要统计完成量
      #@uncomplete_question = get_uncomplete_question(@exercise, User.current)
      # 获取改学生的考试得分
      #@score = calculate_student_score(@exercise, User.current)
      # @score = 100
      # if @uncomplete_question.count < 1
      #   # 查看是否有已提交记录
      #   cur_exercise_user.score = @score
      #   if cur_exercise_user.save
      #   #redirect_to poll_index_path(:polls_group_id => @course.id,:polls_type => 'Course')
      #     @status = 0 #提交成功
      #   else
      #     @status = 2 #未知错误
      #   end
      # else
      #   @status = 1 #有未做得必答题
      # end
      # @save = params[:save].to_i if params[:save]
      respond_to do |format|
        format.js
      end
    end
  end

  # 获取学生未答情况
  def get_student_uncomplete_question
    time_limit = @exercise.time == -1 || @exercise.time.nil?
    uncomplete_count = get_uncomplete_question(@exercise, User.current).count
    uncomplete_shixun = get_uncomplete_shixun(@exercise, User.current).count
    render :json => {:time_limit => time_limit, :uncomplete_count => uncomplete_count, :uncomplete_shixun => uncomplete_shixun}
  end

  def adjust_question_score
    @exercise_question = ExerciseQuestion.where(:id => params[:question]).first
    if @exercise_question.present? && @exercise_question.question_type == 3
      @exercise_answer = @exercise_question.exercise_answers.where(:id => params[:answer]).first
    else
      @exercise_answer = @exercise_question.exercise_shixun_answers.where(:id => params[:answer]).first
    end
  end

  # 主观题打分
  def edit_question_score
    exercise_user = @exercise.exercise_users.where(:user_id => params[:user_id].to_i).first
    @exercise_question = ExerciseQuestion.where(:id => params[:exercise_question_id].to_i).first
    if exercise_user.present? && @exercise_question.present?

      # 分数是否在分值范围内
      unless params[:score].to_i > @exercise_question.question_score || params[:score].to_i < 0
        @score = params[:score].to_i

        if @exercise_question.question_type == 3 || @exercise_question.question_type == 4
          @exercise_answer = ExerciseAnswer.where(:id => params[:answer_id]).first
        else
          @exercise_answer = ExerciseShixunAnswer.where(:id => params[:answer_id]).first
        end
        if @exercise_answer.present?
          @total_score = exercise_user.score
          @exercise_answer.update_attributes(:score => @score)
          # 简答题打分更新主观题分数  其他则更新客观题分数
          if @exercise_question.question_type == 4
            exercise_user.subjective_score = calculate_subjective_score(@exercise, exercise_user.user)
            exercise_user.objective_score =exercise_user.objective_score > 0 ? exercise_user.objective_score : 0
          else
            exercise_user.subjective_score = exercise_user.subjective_score > 0 ? exercise_user.subjective_score : 0
            exercise_user.objective_score = calculate_objective_score(@exercise, exercise_user.user)
          end
          exercise_user.score = exercise_user.subjective_score + exercise_user.objective_score
          exercise_user.save

          if @exercise.tidings.where(:user_id => exercise_user.user_id, :trigger_user_id => User.current, :parent_container_type => "ExerciseScore").count == 0
            @exercise.tidings << Tiding.create(:user_id => exercise_user.user_id, :trigger_user_id => User.current.id, :parent_container_id => @exercise.id, :parent_container_type => "ExerciseScore", :belong_container_id => @exercise.course_id, :belong_container_type => "Course", :viewed => 0, :tiding_type => "Exercise")
          end
          @exercise_answer.exercise_answer_comments << ExerciseAnswerComment.new(:user_id => User.current.id, :exercise_question_id => @exercise_question.id,
                                                                                   :comment => params[:comment][0,1000], :score => @score)
          
          @total_score = exercise_user.score
          if @exercise_question.question_type == 5
            @answer_score = @score
            @score = shixun_question_score(@exercise_question, exercise_user.user)
          end
        end
      else
        @status = 2
        @score = @exercise_question.question_score
      end
    end
  end

  #查看学生的答卷情况
  def show_student_result
    unless params[:pdf]
      if !User.current.logged?
        redirect_to signin_url(:back_url => request.original_url)
        return false
      end
    end
    @exercise = Exercise.find params[:id]
    @course = @exercise.course
    @is_teacher = params[:pdf] ? true : User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
    if @is_teacher || (User.current.member_of_course?(@exercise.course) && @exercise.exercise_status > 2)
      @user = User.find params[:user_id]
      @exercise_questions = @exercise.exercise_questions
      @exercise_user = ExerciseUser.where("user_id =? and exercise_id=?", @user.id, @exercise.id).first
      respond_to do |format|
        if params[:pdf]
          format.html { render :layout => "pdf" }
        else
          format.html { render :layout => "base_edu" }
        end
      end
    else
      render_403
    end
  end

  def back_to_answer
    exercise_user = ExerciseUser.where(:user_id => params[:user_id], :exercise_id => @exercise.id).first
    if exercise_user
      exercise_user.update_attributes(:score => nil, :start_at => nil, :end_at => nil, :status => nil, :commit_status => 0, :objective_score => -1, :subjective_score => -1)
      exercise_user.user.exercise_answer.where(:exercise_question_id => @exercise.exercise_questions.map(&:id)).destroy_all
      exercise_user.user.exercise_shixun_answers.where(:exercise_question_id => @exercise.exercise_questions.map(&:id)).destroy_all
    end
    redirect_to student_exercise_list_exercise_path(@exercise)
  end

  def choose_student
    @sort = params[:sort] ? params[:sort] : "asc"
    if @exercise.exercise_status == 3 || @exercise.end_time < Time.now
      @status = 0
    else
      member = @course.members.where(:user_id => User.current.id).first
      if member.present? && member.teacher_course_groups.count > 0
        user_ids = @course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).map(&:user_id)
        exercise_users = @exercise.exercise_users.where(:commit_status => 1, :user_id => user_ids)
      else
        exercise_users = @exercise.exercise_users.where(:commit_status => 1)
      end
      @exercise_users = exercise_users.includes(:user => [:user_extensions]).order("score #{@sort}")
      if @exercise_users.size == 0
        @status = 2
      end
      if params[:name] || params[:student_id]
        @name = params[:name]
        @student_id = params[:student_id]
        @exercise_users = @exercise_users.where("LOWER(concat(users.lastname, users.firstname)) like '%#{params[:name]}%' and user_extensions.student_id like '%#{params[:student_id]}%'")
      end
    end
  end

  def redo_exercise
    if params[:user_id]
      @exercise.exercise_users.where(:user_id => params[:user_id]).update_all(:score => nil, :start_at => nil, :end_at => nil, :status => nil, :commit_status => 0, :objective_score => -1, :subjective_score => -1)
      ExerciseAnswer.where(:user_id => params[:user_id], :exercise_question_id => @exercise.exercise_questions.pluck(:id)).destroy_all
      ExerciseShixunAnswer.where(:user_id => params[:user_id], :exercise_question_id => @exercise.exercise_questions.pluck(:id)).destroy_all
    end
    redirect_to student_exercise_list_exercise_path(@exercise)
  end

  # 计算学生得分
  def calculate_student_score(exercise, user)
    score = 0
    score1 = 0
    score2 = 0
    score3 = 0
    score4 = 0
    exercise_qustions = exercise.exercise_questions
    exercise_qustions.each do |question|
      if question.question_type != 5
        answer = get_user_answer(question, user)
        standard_answer = get_user_standard_answer(question, user)
        unless answer.empty?
          # 问答题有多个答案
          if question.question_type == 3 && !standard_answer.empty?
            if standard_answer.include?(answer.first.answer_text.strip.downcase)
              score1 = score1+ question.question_score unless question.question_score.nil?
            end
          elsif question.question_type == 1 && !standard_answer.nil?
            if answer.first.exercise_choice.choice_position == standard_answer.exercise_choice_id
              score2 = score2 + question.question_score unless question.question_score.nil?
            end
          elsif question.question_type == 2 && !standard_answer.nil?
            arr = get_mulscore(question, user)
            if arr.to_i == standard_answer.exercise_choice_id
              score3 = score3 + question.question_score unless question.question_score.nil?
            end
          end
        end
      else
        question.exercise_shixun_challenges.each do |exercise_cha|
          game = Game.where(:user_id => user.id, :challenge_id => exercise_cha.challenge_id).first
          if game.present?
            exercise_cha_score = 0
            answer_status = 0
            challeng_path = challenge_path exercise_cha.challenge.path
            if game.status == 2 && game.final_score >= 0
              exercise_cha_score = exercise_cha.question_score
              answer_status = 1
            end
            if exercise_cha.exercise_shixun_answers.where(:user_id => user.id).empty?
              if GameCode.where(:game_id => game.try(:id), :path => challeng_path).first.present?
                game_code = GameCode.where(:game_id => game.try(:id), :path => challeng_path).first
                code = game_code.try(:new_code)
              else
                begin
                  g = Gitlab.client
                  Rails.logger.info "commit_exercise_path---- #{challeng_path}"
                  if game.present?
                    code = g.files(game.myshixun.gpid, challeng_path, "master").try(:content)
                  else
                    code = g.files(question.shixun.gpid, challeng_path, "master").try(:content)
                  end
                  code = tran_base64_decode64(code)
                rescue Exception => e
                  @error_messages = e.message
                  Rails.logger.info "commit_exercise---- #{@error_messages}"
                end
              end
              ExerciseShixunAnswer.create(:exercise_question_id => question.id, :exercise_shixun_challenge_id => exercise_cha.id, :user_id => user.id,
                                          :score => exercise_cha_score, :answer_text => code, :status => answer_status)

            end
            score4 += exercise_cha_score
          end
        end
      end
    end
    score = score1 + score2 + score3 + score4
  end

  # 计算客观题总分
  def calculate_objective_score exercise, user
    score = 0
    score1 = 0
    score2 = 0
    score3 = 0
    score4 = 0
    exercise_qustions = exercise.exercise_questions
    exercise_qustions.each do |question|
      if question.question_type != 5
        answer = get_user_answer(question, user)
        standard_answer = get_user_standard_answer(question, user)
        unless answer.empty?
          # 问答题有多个答案
          if question.question_type == 3 && !standard_answer.empty?
            if answer.first.score.nil? || answer.first.score == -1
              if standard_answer.include?(answer.first.answer_text.strip.downcase)
                score1 = score1 + question.question_score unless question.question_score.nil?
              end
            else
              score1 = score1 + answer.first.score.to_f
            end
          elsif question.question_type == 1 && !standard_answer.nil?
            if answer.first.exercise_choice.choice_position == standard_answer.exercise_choice_id
              score2 = score2 + question.question_score unless question.question_score.nil?
            end
          elsif question.question_type == 2 && !standard_answer.nil?
            arr = get_mulscore(question, user)
            if arr.to_i == standard_answer.exercise_choice_id
              score3 = score3 + question.question_score unless question.question_score.nil?
            end
          end
        end
      else
        question.exercise_shixun_answers.where(:user_id => user.id).each do |answer|
          score4 += answer.score
        end
      end
    end
    score = score1 + score2 + score3 + score4
  end

  # 计算主观题总分
  def calculate_subjective_score exercise, user
    score = 0
    exercise_questions = exercise.exercise_questions.where(:question_type => 4)
    exercise_answers = user.exercise_answer.where(:exercise_question_id => exercise_questions.map(&:id))
    exercise_answers.each do |ea|
      if ea.score != -1
        score += ea.score
      end
    end
    score
  end

  #导入试卷的弹框
  def other_exercise
    # 查作者是我的试卷 进行导入
    #@order,@b_sort = params[:order] || "created_at",params[:sort] || "desc"
    #@r_sort = @b_sort == "desc" ? "asc" : "desc"
    @search = params[:search] ? params[:search].to_s.strip.downcase : ""
    if(params[:type].blank? || params[:type] == "1") #我的题库
      @exercises = User.current.exercise_banks.where(:container_type => "Exercise")
    elsif params[:type] == "2" #公共题库
      @exercises = ExerciseBank.where(:container_type => "Exercise", :is_public => true)
    end
    @type = params[:type] || "1"
    if @search.present?
      course_list_ids = CourseList.where("name like '%#{@search}%'").map(&:id)
      course_list_ids = course_list_ids.length == 0 ? "(-1)" : "("+ course_list_ids.join(",") +")"
      @exercises = @exercises.where("name like '%#{@search}%' or course_list_id in #{course_list_ids}").reorder("created_at desc")
    else
      @exercises = @exercises.reorder("created_at desc")
    end
    @course_id = params[:course_id]
    @is_remote = true
    @page = params[:page].nil? ? 1 : params['page'].to_i
    ex_count = @exercises.count
    @total_pages = (ex_count / 8.0).ceil
    @exercises = paginateHelper @exercises,8
    respond_to do |format|
      format.js
      format.json {
        render json: exercise_bank_json_data(@exercises)
      }
    end
  end

  #搜索导入页面的试卷
  def search_exercises
    @order,@b_sort = params[:order] || "created_at",params[:sort] || "desc"
    @r_sort = @b_sort == "desc" ? "asc" : "desc"
    search = params[:name].to_s.strip.downcase
    courses = User.current.courses.not_deleted.select { |course| User.current.allowed_to?(:as_teacher,course)}
    course_ids = courses.empty? ? "(-1)" : "(" + courses.map { |course| course.id}.join(',') + ")"
    @exercises = Exercise.where("(user_id = #{User.current.id} or course_id in #{course_ids}) and course_id != #{params[:course_id].to_i} and exercise_name like '%#{search}%'").order("#{@order} #{@b_sort}")
    @is_remote = true
    @ex_count = @exercises.count
    @ex_pages = Paginator.new @ex_count, 10, params['page'] || 1
    @offset ||= @ex_pages.offset
    @exercises = paginateHelper @exercises,10
    @course_id = params[:course_id]
    respond_to do |format|
      format.js
    end
  end

  #将选择的试卷导入到班级
  def import_other_exercise
    course_id = params[:course_id]
    course = Course.find(course_id)
    if params[:exercise_id]
      exercise = ExerciseBank.find(params[:exercise_id])
      @exercise = quote_exercise_bank exercise, course
      if @exercise
        @exercise.exercise_questions.where(:question_type => [1, 2, 3]).each do |eq|
          if eq.exercise_standard_answers.count == 0
            @status = 1
            break
          end
        end
      end
    end
  end

  def add_to_exercise_bank
    exercise_bank = User.current.exercise_banks.where(:container_id => @exercise.id, :container_type => "Exercise").first
    if exercise_bank.present?
      exercise_bank.update_attributes(:name => @exercise.exercise_name, :description => @exercise.exercise_description, :course_list_id => @exercise.course.try(:course_list_id))

      question_bank = QuestionBank.where(:container_id => exercise_bank.id, :container_type => exercise_bank.container_type).first
      question_bank.update_attributes(:name => exercise_bank.name, :course_list_id => exercise_bank.course_list_id) if question_bank.present?
      exercise_bank.exercise_bank_questions.destroy_all
    else
      exercise_bank = ExerciseBank.new(:name => @exercise.exercise_name, :description => @exercise.exercise_description, :user_id => User.current.id, :is_public => 0,
                                       :course_list_id => @exercise.course.try(:course_list_id), :container_id => @exercise.id, :container_type => "Exercise", :quotes => 1)
      if exercise_bank.save
        QuestionBank.create(:name => exercise_bank.name, :container_id => exercise_bank.id, :container_type => exercise_bank.container_type,
                            :quotes => exercise_bank.quotes, :user_id => exercise_bank.user_id, :is_public => exercise_bank.is_public, :course_list_id => exercise_bank.course_list_id)
      end
    end
    @exercise.exercise_questions.each do |q|
      option = {
          :question_title => q[:question_title],
          :question_type => q[:question_type] || 1,
          :question_number => q[:question_number],
          :question_score => q[:question_score],
          :shixun_id => q[:shixun_id],
          :shixun_name => q[:shixun_name]
      }
      exercise_bank_question = exercise_bank.exercise_bank_questions.new option

      if q.question_type != 5
        for i in 1..q.exercise_choices.count
          choice_option = {
              :choice_position => i,
              :choice_text => q.exercise_choices[i-1][:choice_text]
          }
          exercise_bank_question.exercise_bank_choices.new choice_option
        end

        for i in 1..q.exercise_standard_answers.count
          standard_answer_option = {
              :exercise_bank_choice_id => q.exercise_standard_answers[i-1][:exercise_choice_id],
              :answer_text => q.exercise_standard_answers[i-1][:answer_text]
          }
          exercise_bank_question.exercise_bank_standard_answers.new standard_answer_option
        end
      else
        for i in 1..q.exercise_shixun_challenges.count
          challenge_option = {
              :position => i,
              :challenge_id => q.exercise_shixun_challenges[i-1][:challenge_id],
              :shixun_id => q.exercise_shixun_challenges[i-1][:shixun_id],
              :question_score => q.exercise_shixun_challenges[i-1][:question_score]
          }
          exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option
        end
      end
    end
    exercise_bank.save
  end

  private
  #测验列表转换为excel
  def exercise_to_xls items
    xls_report = StringIO.new
    book = Spreadsheet::Workbook.new
    sheet1 = book.create_worksheet :name => "exercise"
    blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10
    sheet1.row(0).default_format = blue
    sheet1.row(0).concat([l(:excel_user_id),l(:excel_user_name),l(:excel_nickname),l(:excel_student_id),l(:excel_course_group),l(:excel_mail),l(:excel_objective_score),l(:excel_subjective_score),l(:excel_f_score),l(:excel_answer_time)])
    count_row = 1
    members = @exercise.course.members
    items.each do |exercise|
      sheet1[count_row,0] = exercise.user.id
      sheet1[count_row,1] = exercise.user.show_real_name
      sheet1[count_row,2] = exercise.user.login
      sheet1[count_row,3] = exercise.user.user_extensions.student_id
      sheet1[count_row,4] = member_group_name members, exercise.user.id
      sheet1[count_row,5] = exercise.user.mail
      sheet1[count_row,6] = exercise.objective_score == -1 ? "0.0" : format("%.1f",exercise.objective_score)
      sheet1[count_row,7] = exercise.subjective_score == -1 ? "0.0" : format("%.1f",exercise.subjective_score)
      sheet1[count_row,8] = exercise.score
      sheet1[count_row,9] = exercise.commit_status == 0 ? l(:excel_no_answer) : format_time(exercise.start_at)
      count_row += 1
    end
    book.write xls_report
    xls_report.string
  end

  # ExerciseUser记录用户是否已提交问卷有对应的记录则已提交,没有则新建一个
  def get_exercise_user exercise_id,user_id
    eu = ExerciseUser.find_by_exercise_id_and_user_id(exercise_id,user_id)
    if eu.nil?
      eu = ExerciseUser.new
    end
    eu
  end

  # 获取当前学生回答问题的答案
  def get_user_answer(question,user)
    # user_answer = ExerciseAnswer.where("user_id=? and exercise_question_id=?", user.id, question.id).first
    user_answer = question.exercise_answers.where("#{ExerciseAnswer.table_name}.user_id = #{user.id}")
    user_answer
  end

  # 获取问题的标准答案
  def get_user_standard_answer(question,user)
    if question.question_type == 3
      standard_answer =[]
      question.exercise_standard_answers.each do |answer|
        standard_answer << answer.answer_text.strip.downcase
      end
    else
      standard_answer = question.exercise_standard_answers.first
    end
    standard_answer
  end
  # 是否完成了答题
  def get_complete_question(exercise,user)
    questions = exercise.exercise_questions.includes(:exercise_answers)
    complete_question = []
    questions.each do |question|
      answers = question.exercise_answers.select{|e| e.user_id == user.id}
      if !(answers.nil? || answers.count < 1)
        complete_question << question
      end
    end
    complete_question
  end

  # 获取答题百分比
  def get_percent exercise,user
    complete_count = get_complete_question(exercise,user).count
    if exercise.exercise_questions.count == 0
      return 0
    else
      return (complete_count.to_f / exercise.exercise_questions.count.to_f)*100
    end
  end

  def remove_invalid_exercise(course)
    exercises = course.exercises.where("exercise_name=?","")
    unless exercises.empty?
      exercises.each do |exercise|
        if exercise.exercise_questions.empty?
          exercise.destroy
        end
      end
    end
  end

  def find_exercise_and_course
    @exercise = Exercise.find params[:id]
    @course = Course.find @exercise.course_id
  rescue Exception => e
    render_404
  end

  def find_course
    @course = Course.find params[:course_id]
  rescue Exception => e
    render_404
  end

  #是不是课程的老师
  def teacher_of_course
    render_403 unless User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
  end
end