java_import 'org.bukkit.Location'
require 'yaml'
class Region
  attr_accessor :corner_a, :corner_b , :players, :startpoint, :w, :h, :d, :active?, :created_at, :name
  def initialize(name, corner_a, players=[])
    @players = players
    @corner_a = corner_a
    @corner_b = nil
    @active=false
    @created_at=Time.now
  end

  def corner_b=(arg)
    @corner_b = arg
    ax,ay,az = *@corner_a
    bx,by,bz = *@corner_b
    @w= (ax-bx).abs
    @h= [ay-by].min+50
    @d= (az-bz).abs
    @startpoint = [[ax,bx].min,[ay,by].min+25, [az,bz].min]
  end

  def to_s
    "startpoint: %s, w:%s h:%d, d:%d"%[startpoint.inspect, w,h,d]
  end
  def contains?(event)
    location = event.block.location
    location.x >= @startpoint[0] && location.x <= @startpoint[0]+w &&\
      location.y >= @startpoint[1]-h && location.y <= @startpoint[1] &&\
      location.z >= @startpoint[2] && location.z <= @startpoint[2]+d 
  end
end

class Regionoid
  include Purugin::Plugin, Purugin::Colors
  description 'Regionoid', 1.0

  def find_player(pname, &block)
    p =  server.get_player(pname)
    yield p if p
    p
  end
  def load_regions
    k=(YAML.load(File.open('regoid.yml')))
    puts "loaded #{k.size} regions."
    k
  end
  def save_regions(args)
    puts "saving #{args.inspect}"
    File.open("regoid.yml", 'w') do |f|
      YAML.dump(args, f)
    end
  end
  def on_disable
    puts("writing regions") 
    save_regions(@regions)
  end

  def should_cancel?(e)
    if e.player
      return false if e.player.is_op?
      found = @regions.values.find do |region|
        region.contains?(e)
      end
      if found
        return !found.players.include?(e.player.name)
      end
    else
      false
    end
    false
  end

  def on_enable
    @regions = load_regions
    command("rdump", "dump region defs", "/rdump") do |me, *args|
      me.msg yellow("Dumping #{@regions.size} regions.")
      @regions.each do |name, reg|
        me.msg yellow("region: #{name} #{reg.inspect}")
      end
    end
    event(:block_break) do |e|
      e.cancelled=should_cancel?(e)
    end
    event(:block_place) do |e|
      e.cancelled=should_cancel?(e)
    end

    command("rauser", "add user to region permission" "/rauser <region> <username>") do |me, *args|
      if reg = @regions[args.first]
        if p = server.get_player(args.last)
          reg.players << p.name
          me.msg yellow("Added #{p.name} to #{args.first}")
        end
      end
    end
    command("rduser", "remove user from region" "/rauser <region> <username>") do |me, *args|
      if reg = @regions[args.first]
        if p = server.get_player(args.last)
          reg.players.delete(p.name)
          me.msg yellow("removed #{p.name} from #{args.first}")
        end
      end
    end

    command("rset", "set x coordinate of region", "/setx <regname>") do |me, *args|
      regname = args.first
      loc = [me.location.x.to_i, me.location.y.to_i, me.location.z.to_i]
      if regname and @regions[regname].nil?
        @regions[regname]=Region.new(regname, loc)
      else
        @regions[regname].corner_b=loc
      end
      me.world.get_block_at(Location.new(me.world, *loc)).set_type_id(57)
    end

    command("rinfo", "region info", "/rinfo <regname>") do |me, *args|
      if args.first
        if r = @regions[args.first]
          me.msg yellow("Info for #{r.name}")
          me.msg yellow("Created: #{r.created_at}")
          me.msg yellow("Players: #{r.players.inspect}")
        end
      end

    end
    command("rdel", "delete region", "/rdel <regname>") do |me, *args|
      regname = args.first.strip
      me.msg yellow("Deleted #{regname}") if @regions.delete(regname)
    end
    command("rflush", "delete all regions", "/rdel") do |me, *args|
      @regions.clear
      me.msg yellow("Deleted regions")
    end

    command("ractivate", "activate specified region", "/ractivate <region name>") do |me, *args|
      if args.first
        me.msg "Activating #{args.first}"
        if reg = @regions[args.first]
          reg.active=true
        end
      end
    end
  end

  def build_cube(origin, w, h, d)
    0.upto(h) do |n|
      0.upto(w) do |k|
        0.upto(d) do |m|
          loc =Location.new(me.world, *startpoint)
          loc.y = loc.y - n > 70 ? 70 : loc.y-n
          loc.x = loc.x+k
          loc.z = loc.z + m
          me.world.get_block_at(loc).set_type_id(1)
        end
      end
    end
  end
end
