# 
# This class manages users inscription, login and logout
#
class AccountController < UserController
	model :person
  model :user

  def login
		# Cleaning up
		session[:person] = session[:user] = nil

		login = @params[:person][:name]
		email = @params[:person][:email]
		password = @params[:user][:password]

		@person = Person.find_by_name(login)
		@user = User.find_by_login(login) if @person

		# First we eventually create a new pseudo
		if not @person
			# Create the pseudo
			begin
				Person.transaction(@person) do
					@person = Person.new
					@person.name = login
					if @person.save
						logger.info "person: "+@person.to_s
						logger.info "person.id: "+@person.id.to_s
						flash.now[:notice]  = "Pseudo created"
						session[:person] = @person
					else
						flash.now[:error] = 'Error creating account'
					end
				end
			rescue Exception => e 
				flash.now[:error] = 'Error creating account'
				logger.error e
			end
		end

		if @person and @person.errors.empty?
			# Second we record the password or try to authenticate
			if password.empty?
				if not @user or not @user.salted_password \
					or @user.salted_password.empty?
					session[:person] = @person
				else
					flash.now[:error]  = "This pseudo is protected with a password"
				end
			elsif not @user
				@user = User.new()
				begin
					User.transaction(@user) do
						@user.login = login
						@user.change_password(password)
						# To make sure even a non email protected user can use a password
						@user.email = login+'@nomailyet'
						# This is a hack, to make sure this user can login even if he
						# didn't verify his email
						@user.verified = true
						if @user.save
							flash['notice 2'] = 'Password recorded'

							session[:person] = @person
							session[:user] = @user
						end
					end
				rescue
					flash.now[:error] = 'Error with password'
				end

			elsif User.authenticate(login, password)
				# There is a password protecting this pseudo
				session[:person] = @person
				session[:user] = @user

			elsif not email.empty?
				begin
					User.transaction(@user) do
						if User.authenticate_by_token(@user.id, email)
							@user.change_password(password)
							@user.security_token = nil
							if @user.save
								flash.now['notice 2']  = 'Password successfully modified!'
								session[:person] = @person
								session[:user] = @user
							end
						end
					end
				rescue
					flash.now[:error] = 'Wrong check key'
				end
			else
				flash.now[:error]  = "Wrong password"
			end

			# Third we record the email or send a check_key for a password reset
			if not email.empty?
				if session[:person]
					if email == @person.email
						flash.now['notice 3']  = "Email already recorded and verified"
					else
						signup
					end

				elsif email == @person.email
					# User protected by password and with the same email as entered
          key = @user.generate_security_token
					url =  url_for(:action => 'check_key')
					url += "?user[id]=#{@user.id}&key=#{key}"
					UserNotify::deliver_forgot_password(@user, url)
					flash.now['notice 3']  = "Email with a check key sent to "+email
				end
			end
		end

		render :partial => 'show', :locals => {
			:divId => params[:divId], :choices => getAllVotes }
  end


  def logout
    session[:person] = @person = nil
    session[:user] = @user = nil
		render :partial => 'show', :locals => {
			:divId => params[:divId], :choices => getAllVotes }
  end

  def check_key
		if @user = User.authenticate_by_token(@params[:user][:id], @params[:key])
			#@user = User.find(:first, :conditions => "security_token = '#{params[:key]}'")
			@person = Person.find_by_name(@user.login) if @user
			@person.email = @user.email
			@person.save
			flash.now[:notice] = "Email #{@person.email} verified."
			session[:person] = @person
			session[:user] = @user
			render :text => "<h1>Email verified!</h1> \
				<br/> \
				<a href='#{url_for :controller => 'elt', :action => 'show', :id => nil }'>\
					Back</a>",
				:layout => 'top'
		else
			render :text => "<h3>Sorry, no corresponding check key :-(</h3> \
					<br/> \
					<a href='#{url_for :controller => 'elt', :action => 'show', :id => nil }'>\
						Back</a>",
						:layout => 'top'
		end
	end


	# Mostly copied from the login engine
	protected
  def signup
		if @person and not @user
			@user = User.new
			@user.login = @person.name
		end

		@user.email = @params[:person][:email]
    begin
      User.transaction(@user) do
        unless LoginEngine.config(:use_email_notification)
          @user.verified = 1
        end
        if @user.save
          key = @user.generate_security_token
          #url = url_for(:action => 'home', 'user[id]' => @user.id, :key => key)
					url =  url_for(:action => 'check_key')
					url += "?user[id]=#{@user.id}&key=#{key}"
          #flash[:notice] = 'Signup successful!'
					flash.now['notice 3']  = 'Confirmation email sent to '+@user.email
          if LoginEngine.config(:use_email_notification)
            UserNotify.deliver_signup(@user, params[:user][:password], url)                               
            flash['notice 4'] = ' Please check your registered email account to verify your account registration.'
          end
          #redirect_to :action => 'login'
        end
      end
    rescue Exception => e 
      flash.now[:notice] = nil
      flash.now[:warning] = 'Error creating account: confirmation email not sent'
      logger.error e
    end
  end

	def getAllVotes
		return if !params[:divId]
		elt = Elt.find params[:divId].gsub(/author_/, '')
		Choice.find_all_by_person_id((session[:person] ? session[:person].id : nil),
			:include => 'elt',
			:conditions => "elts.lft >= '#{elt.lft}' AND elts.rgt <= '#{elt.rgt}'")
	end
end