#Copyright (C) 2003 Gimite »ÔÀî <gimite@mx12.freecom.ne.jp>

#ÆüËÜ¸ìÊ¸»ú¥³¡¼¥ÉÈ½ÄêÍÑ¥³¥á¥ó¥È
require 'socket'
require 'thread'
require 'kconv'
require 'jcode'
require 'timeout'
require 'lingr/botkit'
require $REUDY_DIR+'/reudy_common'


module Gimite


#¥Ü¥Ã¥ÈÍÑ¤ÎLingr¥¯¥é¥¤¥¢¥ó¥È
class BotLingrClient < Lingr::BotBase
  
  include(Gimite)
  
  SILENT_SECOND= 20.0 #ÄÀÌÛ¤¬Â³¤¤¤¿¤ÈÈ½ÃÇ¤¹¤ëÉÃ¿ô¡£
  
  def initialize(user)
    @user= user
    @api_key= @user.settings("api_key")
    @email= @user.settings("email")
    @email= nil if @email && @email.empty?
    @password= @user.settings("password")
    @password= nil if @password && @password.empty?
    @main_room_id= @user.settings("main_room_id")
    @info_room_id= @user.settings("info_room_id")
    @rooms= [@main_room_id, @info_room_id].uniq().map(){ |i| {:id => i} }
    @nick= @user.settings("nick")
    @user.client= self
    @user.onBeginConnecting()
    @client= Lingr::LingrClient.new(@api_key, @email, @password)
    @client.bot= self
  end
  
  #¥á¥Ã¥»¡¼¥¸¤ò¤Ò¤¿¤¹¤é½èÍý¤¹¤ë¥ë¡¼¥×¡£
  def processLoop()
    
    while true
      begin
        @client.open() do
          
          for r in @rooms
            @client.enter_room(r[:id], @nick, r[:password])
          end
          @main_room= @client.find_room(@main_room_id)
          @info_room= @client.find_room(@info_room_id)
          @receiveQue= Queue.new() #¼õ¤±¼è¤Ã¤¿ÄÌ¾ïÈ¯¸À¤Î¥­¥å¡¼¡£
          @controlQue= Queue.new() #¼õ¤±¼è¤Ã¤¿À©¸æÈ¯¸À¤Î¥­¥å¡¼¡£
          receiveThread= Thread.new(){ receiveProcess() }
          
          @client.enter_event_loop()
          
          @receiveQue.push(nil)
          receiveThread.join() if receiveThread
          for r in @rooms
            @client.exit_room(r[:id])
          end
          
        end
        return
      rescue Lingr::DisconnectedError
        jputs("ÀÚÃÇ¤µ¤ì¤Þ¤·¤¿¡£")
        sleep(60)
        jputs("ºÆÀÜÂ³Ãæ...")
      end
    end
    
  end
  
  #Êä½õ¾ðÊó¤ò½ÐÎÏ
  def outputInfo(s)
    sleep(@user.settings("wait_before_info").to_f()) if @user.settings("wait_before_info")
    @info_room.say(s)
  end
  
  #È¯¸À¤¹¤ë
  def speak(s)
    @main_room.say(s)
  end
  
  #¥Á¥ã¥ó¥Í¥ë¤ò°ÜÆ°¡£ÀÜÂ³Ãæ¤Ï¤³¤Ã¤Á¤ò»È¤¦¡£
  def moveChannel(channel)
    raise("Not implemented")
  end
  
  #¥Á¥ã¥ó¥Í¥ë¤òÊÑ¹¹¡£ÀÚÃÇÃæ¤Ï¤³¤Ã¤Á¤ò»È¤¦¡£
  def setChannel(channel)
    raise("Not implemented")
  end
  
  def status=(status)
    @main_room.set_nickname(@nick + (status ? "@#{status}" : ""))
  end
  
  #½ªÎ»¡£
  def exit()
    @client.exit_event_loop()
  end
  
  def on_init
    jputs '*** Initialized (CTRL-C to quit)'
    greeting= @user.settings("joining_message")
    speak(greeting) if greeting
    @user.onSelfJoin()
  end

  def on_text(room, mes)
    jputs "#{room.name} > #{mes.nickname}: #{mes.text}"
    if room==@main_room
      for line in mes.text.chomp().split(/\r\n|[\r\n]/)
        @receiveQue.push([mes.nickname, line])
      end
    end
  end

  def on_bot_text(room, mes)
    jputs "#{room.name} > (#{mes.nickname}): #{mes.text}"
  end

  def on_enter(room, mes)
    jputs "#{room.name} > *** #{mes.nickname} has joined the conversation"
    @user.onOtherJoin(mes.nickname) if room==@main_room
  end

  def on_leave(room, mes)
    jputs "#{room.name} > *** #{mes.nickname} has left the conversation"
  end

  def on_nickname_change(room, mes)
    jputs "#{room.name} > *** #{mes.nickname} is now known as #{mes.new_nickname}"
  end

  private
  
  #¼õ¿®¤·¤Æ¥­¥å¡¼¤Ë¤¿¤Þ¤Ã¤Æ¤¤¤ëÈ¯¸À¤ò½èÍý¤¹¤ë¡£
  def receiveProcess()
    while args= popMessage()
      if args==:silent
        @user.onSilent()
      else
        while args
          if @user.settings("wait_before_speak")
            sleep(@user.settings("wait_before_speak").to_f()*(0.5+rand()))
          end
          if @receiveQue.empty?()
            @user.onOtherSpeak(*(args+[false]))
            break
          end
          while !@receiveQue.empty?() && args
            #¥¦¥¨¥¤¥ÈÃæ¤ËÂ¾¤Î¿Í¤ÎÈ¯¸À¤¬Æþ¤Ã¤¿¾ì¹ç¡¢Á°¤ÎÈ¯¸À¤Ï¶ËÎÏÌµ»ë¤¹¤ë¡£
            @user.onOtherSpeak(*(args+[true]))
            args= popMessage()
            return if !args
          end
        end
      end
    end
  end
  
  #¼õ¿®¤·¤Æ¥­¥å¡¼¤Ë¤¿¤Þ¤Ã¤Æ¤¤¤ëÈ¯¸À¤ò¼è¤ê½Ð¤¹¡£
  #À©¸æÈ¯¸À¤¬¤¢¤ì¤ÐÍ¥Àè¤·¤Æ½èÍý¤¹¤ë¡£
  def popMessage()
    while true
      mess= nil
      begin
        Timeout.timeout(SILENT_SECOND) do
          mess= @receiveQue.pop()
        end
      rescue TimeoutError
        mess= :silent
      end
      while !@controlQue.empty?
        @user.onControlMsg(@controlQue.pop())
      end
      return mess if mess!=:nop
    end
  end
  
end


end #module Gimite
