require 'mechanize'

module Mivim # :nodoc:
  class Uploader

=begin rdoc
In order to create valid uploader instance pass credentials of the registered account.
=end
    def initialize(username, password)
      @agent = Mechanize.new do |a|
        a.user_agent_alias = 'Mac Safari'
        a.max_history = 1
      end
      @username = username
      @password = password
    end

=begin rdoc
Logs into the site using credentials passed to constructor.
Returns true value on success and false value if login failed.
=end
    def login
      @agent.get('http://video.miwim.fr/login')
      form = @agent.page.form_with(:name => 'loginForm')
      form.username = @username
      form.password = @password
      form.submit
      login_successful?
    end

=begin rdoc
Checks login status.
Returns true value if logged in and false value otherwise.
=end
    def login_successful?
      !! @agent.page.at('#userinfo #userinfo-title')
    end

=begin rdoc
Uploads video file and returns URL on success.
On failure returns false value.

  +params+ must contain following values:

  :title        name of the video
  :keywords     list of tags assigned to video
  :description  some info about the video
  :category     video channel name (one of the predefined on the site)
  :path         file system path where video file is located

  It is possible to use short category name like "Tech" for "Hi-Tech, science"

  +params+ may contain following values:

  :privacy      indicates video visibility and should be "private" (default) or "public"

=end
    def upload(params = {})
      @params = params
      fill_info
      upload_file if has_upload_form?
      video_link
    rescue
      false
    end

    private

    def fill_info
      @agent.get('/upload')
      form = @agent.page.form_with(:name => 'theForm')
      form.field_myvideo_title = @params[:title]
      form.field_myvideo_keywords = @params[:keywords]
      form.field_myvideo_descr = @params[:description]
      form.checkboxes_with(:name => 'chlist[]').each do |category|
        category_name = category.node.at('.//following-sibling::text()').text.strip
        if category_name.include? @params[:category]
          category.check
          @params[:category_id] = category.value
          break
        end
      end
      form.add_field! 'submit.x', rand(30)
      form.add_field! 'submit.y', rand(30)
      form.submit
    end

    def has_upload_form?
      !! @agent.page.at('form#form_upload')
    end

    def upload_file
      form = @agent.page.form_with(:name => 'form_upload')
      form.action = '/upload'
      form.delete_field!('no_script') rescue nil
      form.delete_field!('upload_range') rescue nil
      form.add_field! 'chlist[]', @params[:category_id]
      form.radiobutton_with(:name => 'field_privacy', :value => (@params[:privacy] || 'private')).check
      form.submit
      @agent.get("/ubr_link_upload.php?config_file=ubr_default_config.php&rnd_id=#{Time.now.to_i}")
      upload_id = @agent.page.root.to_s.match(/startUpload\("([^"]+)"/)[1]
      @agent.get("/ubr_set_progress.php?upload_id=#{upload_id}")
      form.action = "/cgi-bin/ubr_upload.pl?upload_id=#{upload_id}"
      form.file_uploads.first.file_name = @params[:path]
      form.submit
      @agent.get("/upload?upload_id=#{upload_id}")
    end

    def video_link
      @agent.page.at('input[name="video_link"]')[:value] rescue nil
    end
  end
end
