class Contest < ActiveRecord::Base
  attr_accessible :author_id, :budget, :commit, :deadline, :description, :name, :password
  include Redmine::SafeAttributes

  belongs_to :author, :class_name => 'User', :foreign_key => :author_id
  has_many :contesting_projects, :dependent => :destroy
  has_many :projects, :through => :contesting_projects
  has_many :contesting_softapplications, :dependent => :destroy
  has_many :softapplications, :through => :contesting_softapplications, :dependent => :destroy
  has_many :projects_member, :class_name => 'User', :through => :projects
  has_many :journals_for_messages, :as => :jour, :dependent => :destroy
  has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
  has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy
  has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy
  has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
  has_many :contestnotifications, :dependent => :destroy, :include => :author




  acts_as_attachable

  NAME_LENGTH_LIMIT = 60
  DESCRIPTION_LENGTH_LIMIT = 250
  validates :name, length: {maximum: NAME_LENGTH_LIMIT}, presence: true
  validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT}
  validates :author_id, presence: true
  validates :budget, presence: true
  validates :deadline, format: {:with =>/^[1-9][0-9]{3}\-0?[1-9]|1[12]\-0?[1-9]|[12]\d|3[01]$/}
  validate :validate_user
  after_create :act_as_activity

  scope :visible, lambda {|*args|
    nil
  }

  scope :like, lambda {|arg|
    if arg.blank?
      where(nil)
    else
      pattern = "%#{arg.to_s.strip.downcase}%"
      where("LOWER(id) LIKE :p OR LOWER(name) LIKE :p OR LOWER(description) LIKE :p", :p => pattern)
    end
  }

  acts_as_watchable
  acts_as_taggable

  acts_as_event :title => Proc.new {|o| "#{l(:label_requirement)} ##{o.id}: #{o.name}" },
                :description => :description,
                :author => :author,
                :url => Proc.new {|o| {:controller => 'contests', :action => 'show_contest', :id => o.id}}

  acts_as_activity_provider :find_options => {:include => [:projects, :author]},
                            :author_key => :author_id

  safe_attributes 'name',
    'description',
    'budget',
    'deadline',
    'password'


  def add_jour(user, notes, reference_user_id = 0, options = {})
    if options.count == 0
      self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id)
    else
      jfm = self.journals_for_messages.build(options)
      jfm.save
      jfm
    end
  end

  # modified by longjun
  # 这个函数没有用到
  # def self.creat_contests(budget, deadline, name, description=nil)
    # self.create(:author_id => User.current.id, :budget => budget,
                # :deadline => deadline, :name => name, :description => description, :commit => 0)
  # end
  # end longjun 
  
  def update_contests(budget, deadline, name, description=nil)
    if(User.current.id == self.author_id)
    self.name = name
    self.budget = budget
    self.deadline = deadline
    self.description = description
    self.save
    end
  end

  def delete_contests
    unless self.nil?
      if User.current.id == self.author_id
      self.destroy
      end
    end
  end

  # Closes open and locked project versions that are completed
  def close_completed_versions_contest
    Version.transaction do
      versions.where(:status => %w(open locked)).all.each do |version|
        if version.completed?
          version.update_attribute(:status, 'closed')
        end
      end
    end
  end

  def set_commit(commit)
    self.update_attribute(:commit, commit)
  end

  private

  def validate_user
    errors.add :author_id, :invalid if author.nil? || !author.active?
  end


  def act_as_activity
    self.acts << Activity.new(:user_id => self.author_id)
  end

  def validate_contest_manager(user_id)
    unless user_id.nil?
      if self.author_id == user_id
      return true
      else
      return false
      end
    end
  end
end
