require "./pixel_image.rb"
require "digest"

class ImageUtils
  @@magickImg = nil
  @@pixelImg = nil

  @@password = ""
  @@message = ""

  @@hash = nil

  def initialize(pass, msg, i)
    @@password = pass
    @@message  = msg

    if msg.length > 1024 then
      puts "Maximum length exceeded.  Exiting."
      exit
    end

    @@magickImg = i

    @@pixelImg = PixelImage.new(@@magickImg)

    self.generateHash
  end

  def getImage
    return @@pixelImg
  end

  def generateHash
    h = Digest::SHA512.hexdigest(@@password)
    s = @@pixelImg.getSalt

    @@hash = Digest::SHA512.hexdigest(self.interlaceHash(h, s))
  end

  def interlaceHash(h1, h2)
    puts h1
    puts h2

    h1 = self.getBits(h1)
    h2 = self.getBits(h2)
    
    interlaced = 0

    while h1.to_i > 0 and h2.to_i > 0 do
      interlaced = (interlaced << 1) | (h1 & 1)
      h1 = h1 >> 1
      interlaced = (interlaced << 1) | (h2 & 1)
      h2 = h2 >> 1

#      puts interlaced
#      puts h1
#      puts h2
    end

    puts interlaced.to_s.inspect

    return interlaced.to_s
  end

  def generateLookupTable
    tbl = []

    hash_bits = @@pixelImg.getBits(@@hash)
    msg_bits = @@pixelImg.getBits(@@message)

    # gross, but pad in the 24 bits that will become the msg length
    # and padding bits...
    msg_bits = msg_bits << 24

    while msg_bits > 0 do
      loc = nil

      loop do
        x = (hash_bits.to_i % @@pixelImg.getSize[:width])
        y = (hash_bits.to_i % @@pixelImg.getSize[:height])

        loc = {"x": x, "y": y}

      break if !tbl.include?(loc)
        hash_bits = hash_bits >> 1

        if hash_bits <= 0 then
          puts
          puts "wow too much data"
          puts "leftover bits: " + msg_bits.to_s(36)
          exit
        end
      end

      hash_bits = hash_bits >> 1

      tbl.push(loc)

      msg_bits = msg_bits >> 6
    end

    return tbl
  end

  def getBits(o)
    msg_bytes = o.unpack("c*")

    msg_bits = 0

    for b in msg_bytes
      msg_bits = (msg_bits << 8) | b
    end

    return msg_bits
  end
end