module Potato
  module DAmn
    # @api private
    # Manages packets received from dAmn
    module Events
      # @param [DAmn::Packet] pkt
      # @return [void]
      def on_login pkt
        @user.logged_in = true
      end
      
      # @param [DAmn::Packet] pkt
      # @return [void]
      def on_ping pkt
        send_packet "pong"
      end
      
      # @param [DAmn::Packet] pkt
      # @return [void]
      def on_join pkt
        @user.join(pkt.room)
      end
      
      # @param [DAmn::Packet] pkt
      # @return [void]
      def on_part pkt
        @user.part(pkt.room)
      end
      
      # @param [DAmn::Packet] pkt
      # @return [void]
      def on_property pkt
        if pkt.param =~ /login:/ && @whoising
          @user.whois(pkt.param.sub("login:", ""), pkt)
          @whoising = false
        else
          case pkt.args[:p]
          when "topic"
            @user.topic(pkt.room, pkt.body.decode_entities, pkt.args[:by], pkt.args[:ts])
          when "members"
            @user.names(pkt.room, pkt.subpkts)
          when "privclasses"
            @privclasses[pkt.room] = Hash[pkt.body.split(/\n/).map{|x|[x.split(":")[1], x.split(":")[0].to_i]}]
          end
        end
      end
      
      # @param [DAmn::Packet] pkt
      # @return [void]
      def on_recv pkt
        case pkt.subpkts[0].cmd
        when "action", "msg"
          @user.send(pkt.subpkts[0].cmd.to_sym,
            pkt.room,
            pkt.subpkts[0].args[:from],
            pkt.body) unless pkt.body.to_tags.strip == @user.config.last_line.strip
        when "join", "part"
          @server.write("get login:#{pkt.subpkts[0].param}\np=info\n\0")
          @user.send((pkt.subpkts[0].cmd + "s").to_sym,
            pkt.subpkts[0].param, pkt.room,
            Packet.new(@server.readline("\0")).subpkts.count{|x|x.cmd == "ns" && x.param == "chat:#{pkt.room}"},
            begin; pkt.subpkts[1].cmd.gsub(/\w+=/, ""); rescue; nil; end,
            begin; pkt.subpkts[1].args[:r]; rescue; nil; end)
        when "kicked"
          @user.kick(pkt.room, pkt.subpkts[0].param, pkt.subpkts[0].args[:by], pkt.subpkts[0].body)
        when "admin"
          case pkt.subpkts[0].param
          when "create", "update"
            @user.send("#{pkt.subpkts[0].param}_privclass".to_sym,
              pkt.room, *pkt.subpkts[0].args.values_at(:name, :privs, :by))
          when "rename"
            @user.rename_privclass(pkt.room, *pkt.subpkts[0].args.values_at(:prev, :name, :by))
          when "remove"
            @user.remove_privclass(pkt.room, *pkt.subpkts[0].args.values_at(:name, :by))
          end
        when "privchg"
          @user.move_user(pkt.room, pkt.subpkts[0].param, pkt.subpkts[0].args[:pc], pkt.subpkts[0].args[:by])
        end
      end
    end
  end
end