local Object = require 'libs.classic'

local Randomizer = Object:extend()

local highest_count = 0

function Randomizer:new(always, seed)
    self.always = always
    if seed ~= nil then
        self.seed = seed
    else
        self.seed = love.math.random(1, 9007199254740991)
    end
    self.drought = {
    I = 0,
    J = 0,
    L = 0,
    T = 0,
    S = 0,
    Z = 0,
    O = 0
    }
    self.droughted_deals = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    self.piece_counts = {
    I = 0,
    J = 0,
    L = 0,
    T = 0,
    S = 0,
    Z = 0,
    O = 0
    }
    self.piece_round = 0
    self:initialize()
end

function Randomizer:nextPiece()
    return self:generatePiece()
end

function Randomizer:runTest()
    local i_distance = 0
    local highest_distance = 0
    local distance_total = 0
    local i_appearances = 0
    local dupe = 0
    local trip = 0
    local quad = 0
    local quin = 0
    local lastpiece = 0
    local lastpiece2 = 0
    local lastpiece3 = 0
    local lastpiece4 = 0
    local pieceseq_rep = 0
    local pieceseq = {}
    local last_pieceseq = {}
    local highest_discrepancy = 0
    local discrepancy = self.piece_counts[table.highest(self.piece_counts)] - self.piece_counts[table.lowest(self.piece_counts)]
    local total_chance = 0
    for i=0, 750000 do
        piece = self:generatePiece()
        if #pieceseq < 7 then
            table.insert(pieceseq, piece)
        else
			--print(table.concat(pieceseq))
			if table.concat(pieceseq) == table.concat(last_pieceseq) then
				pieceseq_rep = pieceseq_rep + 1 
			end
            last_pieceseq = copy(pieceseq)
            pieceseq = {}
        end
        if piece == lastpiece then dupe = dupe + 1 end
        if piece == lastpiece and piece == lastpiece2 then trip = trip + 1 end
        if piece == lastpiece and piece == lastpiece2 and piece == lastpiece3 then quad = quad + 1 end
        if piece == lastpiece and piece == lastpiece2 and piece == lastpiece3 and piece == lastpiece4 then quin = quin + 1 end
        if piece == 'I' then 
            distance_total = distance_total + i_distance
            i_appearances = i_appearances + 1
            i_distance = 0
        else i_distance = i_distance + 1 end
        if highest_distance < i_distance then highest_distance = i_distance end
        lastpiece4 = lastpiece3
        lastpiece3 = lastpiece2
        lastpiece2 = lastpiece
        lastpiece = piece
        --if self.piece_round <= 750 then print(discrepancy) end
        local new_discrepancy = self.piece_counts[table.highest(self.piece_counts)] - self.piece_counts[table.lowest(self.piece_counts)]
        if new_discrepancy > discrepancy then highest_discrepancy = new_discrepancy end
		discrepancy = new_discrepancy
		local chance = 0
		for piece,drought in pairs(self.drought) do
			local piece_chance = 0.14/( ((self.drought[table.highest(self.drought)]+1)-drought) / (self.drought[table.highest(self.drought)]) )
			chance = chance + piece_chance
		end
		chance = chance / 7
		total_chance = total_chance + chance
    end
    --something = something / 750000
    print(string.format('dupes: %d, trips: %s, quads: %s, quins: %s, highest i distance: %d, average i distance: %f, pieceseq reps: %d, highest discrepancy:%d, average chance:%f\ndrought lengths dealt: %s', dupe, trip, quad, quin, highest_distance, distance_total/i_appearances, pieceseq_rep, highest_discrepancy, total_chance/750000, table.concat(self.droughted_deals, '-')))
	for piece,count in pairs(self.piece_counts) do
		print(piece..' '..count)
	end
end

function Randomizer:initialize()
	local start_pieces = {"I", "J", "L", "T"}
	local shapes = {"I", "J", "L", "T", "S", "Z", "O"}
    love.math.setRandomSeed(self.seed)
    self.drought[table.remove(shapes, love.math.random(1, 4))] = 10
	for i=4,9 do
		self.drought[table.remove(shapes, love.math.random(1, #shapes))] = i
	end
	
	--self:runTest()
end

function Randomizer:generatePiece(always)
	if self.always then
		return "I"
	end

	local shapes = {"I", "J", "L", "T", "S", "Z", "O"}
	local new_piece = shapes[love.math.random(1,7)]
	local chance = love.math.random(0,self.drought[table.highest(self.drought)])
	while self.drought[new_piece] < chance do
		new_piece = shapes[love.math.random(1,7)]
	end
	for piece,drought in pairs(self.drought) do
		if drought >= 10 then 
			new_piece = piece 
		end
	end
	generated_piece = new_piece

	for piece,drought in pairs(self.drought) do
		if new_piece ~= piece then self.drought[piece] = self.drought[piece] + 1
		else 
			if drought < #self.droughted_deals then self.droughted_deals[drought+1] = self.droughted_deals[drought+1] + 1 end
			self.piece_counts[piece] = self.piece_counts[piece] + 1
			self.drought[piece] = 0 
		end
	end
	self.piece_round = self.piece_round + 1
	
	return generated_piece
end

return Randomizer
