# Each Node of the repository can have multiple Attachments associated with it.
# This controller is used to handle REST operations for the attachments.
class AttachmentsController < ApplicationController
  before_filter :login_required

  # Retrieve all the associated attachments for a given :node_id
  def index
    @attachments = Node.find(params[:node_id]).attachments
    respond_to do |format|
      format.html{ render :action => 'index'}
      format.json{ render :json => @attachments }
    end
    @attachments.each do |a| a.close end
  end

  # Create a new attachment for a give :node_id using a file that has been 
  # submitted using an HTML form POST request.
  def create
    # TODO: what happens with files if they already exist?
    @attachment = Attachment.new(params['attachment_file'].original_filename, :node_id => params[:node_id])
    @attachment << params['attachment_file'].read
    @attachment.save
    
    # Note: this breaks the basic html scaffolds, but is required for the FileTree 
    # extension
    #redirect_to node_attachments_path(params[:node_id])
    render :text => {:success => true}.to_json
  end

  # It is possible to rename attachments and this function provides that
  # functionality.
  def update
    attachment = Attachment.find(params[:id], :conditions => {:node_id => Node.find(params[:node_id]).id})
    attachment.close
    new_name = CGI::unescape( params[:rename] )
    destination = File.expand_path( File.join( Attachment.pwd, params[:node_id], new_name ) )
    if !File.exist?(destination) && ( !destination.match(/^#{Attachment.pwd}/).nil? )
      File.rename( attachment.fullpath, destination  )
    end
    redirect_to :action => 'show', :id => params[:rename]
  end

  # This function will send the Attachment file to the browser. It will try to 
  # figure out if the file is an image in which case the attachment will be 
  # displayed inline. By default the <tt>Content-disposition</tt> will be set to
  # +attachment+.
  def show
    # we send the file name as the id, the rails parser however split the filename
    # at the fullstop so we join it again
    filename = params[:id]
    @attachment = Attachment.find(filename, :conditions => {:node_id => Node.find(params[:node_id]).id})

    # Figure out the best way of displaying the file (by default send the it as
    # an attachment).
    extname = File.extname(filename)[1..-1]
    disposition = 'attachment'
    if extname
      # account for the possibility of this being an image and present the
      # attachment inline
      mime_type = Mime::Type.lookup_by_extension(extname)
      content_type = mime_type.to_s unless mime_type.nil?
      if content_type.match('image')
        disposition = 'inline'
      end
    end

    send_data(@attachment.read, :type => content_type,
      :filename => @attachment.filename,
      :disposition => disposition)

    @attachment.close
  end

  # Invoke this method to delete an Attachment from the server. It receives the
  # attachment's file name in the :id parameter and the corresponding node in
  # the :node_id parameter.
  def destroy
    # we send the file name as the id, the rails parser however split the filename
    # at the fullstop so we join it again
    filename = params[:id]
    @attachment = Attachment.find(filename, :conditions => {:node_id => Node.find(params[:node_id]).id})
    @attachment.delete
    redirect_to node_attachments_path(params[:node_id])
  end
  
end
