class QuestionsController < ApplicationController
  unloadable

  before_filter :find_optional_project, :only => [:autocomplete_for_topic, :topics]
  before_filter :find_optional_board, :only => [:autocomplete_for_topic, :topics]
  before_filter :find_topic, :authorize, :only => :vote
  before_filter :find_topics, :only => [:topics, :autocomplete_for_topic]

  helper :questions
  if Redmine::VERSION.to_s > '2.1'
    helper :boards
  end
  include QuestionsHelper

  def index
    @boards = Board.visible.includes(:last_message => :author).includes(:messages).order(:project_id)
    # show the board if there is only one
    if @boards.size == 1
      @board = @boards.first
      redirect_to project_board_url(@board, :project_id => @board.project)
    else
      render "boards/index"
    end
  end

  def topics
  end

  def vote
    User.current.voted_for?(@topic) ? @topic.dislike(User.current.becomes(Principal)) : @topic.like(User.current.becomes(Principal))
    respond_to do |format|
      format.html { redirect_to_referer_or {render :text => (watching ? 'Vote added.' : 'Vote removed.'), :layout => true}}
    end
  end

  def autocomplete_for_topic
    render :layout => false
  end

  def convert_issue
    issue = Issue.visible.find(params[:issue_id])
    board = Board.visible.find(params[:board_id])
    message = Message.new
    message.author = issue.author
    message.created_on = issue.created_on
    message.board = board
    message.subject = issue.subject
    message.content = issue.description.blank? ? issue.subject : issue.description
    message.watchers = issue.watchers
    message.add_watcher(issue.author)
    message.attachments = issue.attachments
    issue.journals.select{|j| !j.notes.blank?}.each do |journal|
      reply = Message.new
      reply.author = journal.user
      reply.created_on = journal.created_on
      reply.subject = "Re: #{message.subject}"
      reply.content = journal.notes
      reply.board = board
      message.children << reply
    end
    if message.save
      issue.destroy if params[:destroy]
      redirect_to board_message_path(board, message)
    else
      redirect_back_or_default({:controller => 'issues', :action => 'show', :id => issue})
    end

  end

private

  def find_topics
    seach = params[:q] || params[:topic_search]

    columns = ["subject", "content"]
    tokens = seach.to_s.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect{|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}.uniq.select {|w| w.length > 1 }
    tokens = [] << tokens unless tokens.is_a?(Array)
    token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
    sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(' AND ')
    find_options = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]

    scope = Message.joins(:board).where({})
    scope = scope.where("#{Message.table_name}.parent_id IS NULL")
    scope = scope.where(["#{Board.table_name}.project_id = ?", @project.id]) if @project
    scope = scope.where(["#{Message.table_name}.board_id = ?", @board.id]) if @board
    scope = scope.where(find_options) unless tokens.blank?
    scope = scope.visible.includes(:board).order("#{Message.table_name}.updated_on DESC")

    @topic_count = scope.count
    @limit =  per_page_option
    @topic_pages = Paginator.new(self, @topic_count, @limit, params[:page])
    @offset = @topic_pages.current.offset
    scope = scope.limit(@limit).offset(@offset)
    scope = scope.tagged_with(params[:tag]) unless params[:tag].blank?
    @topics = scope
  end

  def find_topic
    @topic = Message.visible.find(params[:id]) unless params[:id].blank?
    @board = @topic.board
    @project = @board.project
  rescue ActiveRecord::RecordNotFound
    render_404
  end

  def find_optional_board
    @board = Board.visible.find(params[:board_id]) unless params[:board_id].blank?
    @project = @board.project if @board
    allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @project, :global => true)
    allowed ? true : deny_access
  rescue ActiveRecord::RecordNotFound
    render_404
  end



end
