--sumsung_1x
local TBL_WORDLINE =
{
	{0x00,   -1,   -1},
	{0x01,   -1, 0x02},
	{0x03,   -1, 0x04},
	{0x05, 0x06, 0x07},
	{0x08, 0x09, 0x0A},
	{0x0B, 0x0C, 0x0D},
	{0x0E, 0x0F, 0x10},
	{0x11, 0x12, 0x13},
	{0x14, 0x15, 0x16},
	{0x17, 0x18, 0x19},
	{0x1A, 0x1B, 0x1C},
	{0x1D, 0x1E, 0x1F},
	{0x20, 0x21, 0x22},
	{0x23, 0x24, 0x25},
	{0x26, 0x27, 0x28},
	{0x29, 0x2A, 0x2B},
	{0x2C, 0x2D, 0x2E},
	{0x2F, 0x30, 0x31},
	{0x32, 0x33, 0x34},
	{0x35, 0x36, 0x37},
	{0x38, 0x39, 0x3A},
	{0x3B, 0x3C, 0x3d},
	{0x3E, 0x3F, 0x40},
	{0x41, 0x42, 0x43},
	{0x44, 0x45, 0x46},
	{0x47, 0x48, 0x49},
	{0x4A, 0x4B, 0x4C},
	{0x4D, 0x4E, 0x4F},
	{0x50, 0x51, 0x52},
	{0x53, 0x54, 0x55},
	{0x56, 0x57, 0x58},
	{0x59, 0x5A, 0x5B},
	{0x5C, 0x5D, 0x5E},
	{0x5F, 0x60, 0x61},
	{0x62, 0x63, 0x64},
	{0x65, 0x66, 0x67},
	{0x68, 0x69, 0x6A},
	{0x6B, 0x6C, 0x6D},
	{0x6E, 0x6F, 0x70},
	{0x71, 0x72, 0x73},
	{0x74, 0x75, 0x76},
	{0x77, 0x78, 0x79},
	{0x7A, 0x7B, 0x7C},
	{0x7D, 0x7E, 0x7F},
	{0x80, 0x81, 0x82},
	{0x83, 0x84, 0x85},
	{0x86, 0x87, 0x88},
	{0x89, 0x8A, 0x8B},
	{0x8C, 0x8D, 0x8E},
	{0x8F, 0x90, 0x91},
	{0x92, 0x93, 0x94},
	{0x95, 0x96, 0x97},
	{0x98, 0x99, 0x9A},
	{0x9B, 0x9C, 0x9D},
	{0x9E, 0x9F, 0xA0},
	{0xA1, 0xA2, 0xA3},
	{0xA4, 0xA5, 0xA6},
	{0xA7, 0xA8, 0xA9},
	{0xAA, 0xAB, 0xAC},
	{0xAD, 0xAE, 0xAF},
	{0xB0, 0xB1, 0xB2},
	{0xB3, 0xB4, 0xB5},
	{0xB6, 0xB7, 0xB8},
	{0xB9, 0xBA, 0xBB},
	{0xBC, 0xBD, 0xBE},
	{0xBF, 0xC0, 0xC1},
	{0xC2, 0xC3, 0xC4},
	{0xC5, 0xC6, 0xC7},
	{0xC8, 0xC9, 0xCA},
	{0xCB, 0xCC, 0xCD},
	{0xCE, 0xCF, 0xD0},
	{0xD1, 0xD2, 0xD3},
	{0xD4, 0xD5, 0xD6},
	{0xD7, 0xD8, 0xD9},
	{0xDA, 0xDB, 0xDC},
	{0xDD, 0xDE, 0xDF},
	{0xE0, 0xE1, 0xE2},
	{0xE3, 0xE4, 0xE5},
	{0xE6, 0xE7, 0xE8},
	{0xE9, 0xEA, 0xEB},
	{0xEC, 0xED, 0xEE},
	{0xEF, 0xF0, 0xF1},
	{0xF2, 0xF3, 0xF4},
	{0xF5, 0xF6, 0xF7},
	{0xF8, 0xF9, 0xFA},
	{0xFB,   -1, 0xFC},
	{0xFD,   -1, 0xFE},
	{0xFF,   -1,   -1},
}


local wlcount = 88
local cellNum = 3

local btnew = ByteArray.new
local btget = ByteArray.get
local btset = ByteArray.set
local bt2Str = ByteArray.tostring
local bt2Array = ByteArray.toarray
local btcopy = ByteArray.arraycopy

local pgetstr = Param.getString
local pgetint = Param.getInt
local pgetintx = Param.getIntEx
local pgetmask = Param.getMask

local band = Bit.band
local bor = Bit.bor
local bxor = Bit.bxor
local bnot = Bit.bnot
local ls = Bit.lshift
local rs = Bit.rshift

local trace = Debug.trace
--local msgbox = Debug.msgbox

local c_table =
{
    -- Automatically generated by GPTableGen.exe v.1.0
    --
    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
}

function ALLOC_SPACE(n, unit)
    return math.floor((n + unit - 1) / unit)
end

function curTime()
    return os.date("%H:%M:%S").."  "
end

function dbgprint(s)
    trace(curTime()..s)
end

function getbitcount(buf, len, bitvalue)
	local value
	local count = 0
	for i = 0, len-1 do
		value = btget(buf, i)
		count = count + c_table[value + 1]
	end

	if bitvalue == 0 then
		count = len - count
	end

	return count
end

function getbytebit()
	return c_table[byte + 1]
end

function countTable(mytab, ubou)
	local count = 0
	for i = 0, ubou - 1 do
		if mytab[i] ~= nil then
			count = count + 1
		end
	end

	return count
end

function setbitvalue(buff, bit, value)
	local byte = btget(buff, math.floor(bit / 8))
	if value == 1 then
		byte = bor(byte, ls(1, math.fmod(bit, 8)))
	else
		byte = band(byte, bnot(ls(1, math.fmod(bit, 8))));
	end
	btset(buff, math.floor(bit / 8), byte)
end

--[[------------------------------------------------------------
function Analyzer(buf, len, PlaneCount, PageCount, BlockCount, EccBytes)
	dbgprint("=============start================")
	local PageMaskLen = ALLOC_SPACE(PageCount, 8)
	local BlockMaskLen = ALLOC_SPACE(BlockCount, 8)

	local PageMask = btnew(PageMaskLen * PlaneCount, 0)
	local BlockMask = btnew(BlockMaskLen, 0)

	local bytes = bt2Str(buf, len)

	for i = 0, len - 1 do

	end

	dbgprint("==============end=================")
	return 100, PageMask, BlockMask
end
---------------------------------------------------------------]]

--	local AmaskStr = pgetmask(1)
--	AmaskStr = string.gsub(AmaskStr, "%[S%]", "")

--	local APageMask = btnew(PageMaskLen, 0)
--	for i=0, PageMaskLen*2-1, 2 do
--		btset(APageMask, math.floor(i / 2), tonumber(string.sub(AmaskStr, i + 1, i + 2), 16))
--	end

function GetWLOfPage(page)
	local wl = 1
	for wl=1, wlcount do
		for i=1, 3 do
			if TBL_WORDLINE[wl][i] == page then
				return wl
			end
		end
	end

	return -1
end

--[[
function GetWLOfOrder(page)
	local wl = 1
	for wl=1, wlcount do
		for i=1, 3 do
			if TBL_ORDER[wl][i] == page then
				return wl
			end
		end
	end

	return -1
end
]]

function IsAPage(page)
	local wl = 1
	for wl=1, wlcount do
		if TBL_WORDLINE[wl][1] == page then
			return true
		end
	end

	return false
end

--[[
function IsAInOrder(page)
	local wl = 1
	for wl=1, wlcount do
		if TBL_ORDER[wl][1] == page then
			return true
		end
	end

	return false
end
]]

function ConvertPageWordLineBuff(pPageBuffer, nBlock, nPhyPage, nValidPage)
	dbgprint("=============ConvertPageWordLineBuff start================")
	local wl = 0
	local byte
	local pWordLineBuffer = btnew(nBlock * wlcount, 0)

	local tb = {}
	for page=0, nPhyPage-1 do
		tb[page] = GetWLOfPage(page) - 1
	end

	for block=0, nBlock-1 do
		for page=0, nValidPage-1 do
			--wl = GetWLOfPage(page) - 1
			wl = tb[page]
			byte = btget(pPageBuffer, block * nPhyPage + page)
			btset(pWordLineBuffer, block * wlcount + wl, math.max(byte, btget(pWordLineBuffer, block * wlcount + wl)))
		end
	end

	dbgprint("=============end================")
	return wlcount, pWordLineBuffer
end

function ConvertSlcPage2WordLineBuff(pPageBuffer, nBlock, nPhyPage, nValidPage)
	dbgprint("=============ConvertSlcPage2WordLineBuff start================")
	local wl = 0
	local byte
	local pWordLineBuffer = btnew(nBlock * wlcount, 0)

	local tb = {}
	for page=0, nPhyPage-1 do
		if IsAInOrder(page) then
			tb[page] = GetWLOfOrder(page) - 1
		end
	end

	for block=0, nBlock-1 do
		for page=0, nValidPage-1 do
			if tb[page] then
				wl = tb[page]
				byte = btget(pPageBuffer, block * nPhyPage + page)
				btset(pWordLineBuffer, block * wlcount + wl, byte)
			end
		end
	end

	dbgprint("=============end================")
	return wlcount, pWordLineBuffer
end

function ConvertSectorWordLineBuff(pSectorBuffer, nBlock, nPhyPage, nValidPage, nSectorCnt)
	dbgprint("=============ConvertSectorWordLineBuff start================")
	local wl = 0
	local btMin, btCur
	local pWordLineBuffer = btnew(nBlock * nValidPage * nSectorCnt, 0)

	local tb = {}
	for page=0, nPhyPage-1 do
		tb[page] = GetWLOfPage(page) - 1
	end

	for block=0, nBlock-1 do
		for page=0, nValidPage-1 do
			wl = tb[page]
			for sec=0, nSectorCnt do
				btCur = btget(pSectorBuffer, (block * nPhyPage + page) * nSectorCnt + sec)
				btMin = btget(pWordLineBuffer, (block * wlcount + wl) * nSectorCnt + sec)
				btset(pWordLineBuffer, (block * wlcount + wl) * nSectorCnt + sec, math.max(btCur, btMin))
			end
		end
	end

	dbgprint("=============end================")
	return wlcount, pWordLineBuffer
end

function ConvertSlcSectorWordLineBuff(pSectorBuffer, nBlock, nPhyPage, nValidPage, nSectorCnt)
	dbgprint("=============ConvertSlcSectorWordLineBuff start================")
	local wl = 0
	local btMin, btCur
	local pWordLineBuffer = btnew(nBlock * nValidPage * nSectorCnt, 0)

	local tb = {}
	for page=0, nPhyPage-1 do
		if IsAInOrder(page) then
			tb[page] = GetWLOfOrder(page) - 1
		end
	end

	for block=0, nBlock-1 do
		for page=0, nValidPage-1 do
			if tb[page] then
				wl = tb[page]
				for sec=0, nSectorCnt do
					--btCur = btget(pSectorBuffer, (block * nPhyPage + page) * nSectorCnt + sec)
					btMin = btget(pWordLineBuffer, (block * wlcount + wl) * nSectorCnt + sec)
					btset(pWordLineBuffer, (block * wlcount + wl) * nSectorCnt + sec, btMin)
				end
			end
		end
	end

	dbgprint("=============end================")
	return wlcount, pWordLineBuffer
end

function GetWordlinePageMask(PageMask, PageCount)
	dbgprint("=============GetWordlinePageMask start================")
	local PageMaskLen = ALLOC_SPACE(PageCount, 8)
	local RetPageMask = btnew(PageMaskLen, 0)
	local PageArray = {}

	for page=0, PageCount-1 do
		byte = btget(PageMask, math.floor(page / 8))
		if band(byte, ls(1, math.fmod(page, 8))) ~= 0 then
			PageArray[page] = page
		end
	end

	for wl=1, wlcount do
		bGoodWL = true
		for i=1, cellNum do
			if TBL_WORDLINE[wl][i] ~= -1 then
				if PageArray[TBL_WORDLINE[wl][i]] == nil then
					bGoodWL = false
					break
				end
			end
		end

		if bGoodWL then
			setbitvalue(RetPageMask, wl-1, 1)
		end
	end

	dbgprint("=============end================")
	return wlcount, RetPageMask
end

function GetSlcWordlinePageMask(PageMask, PageCount)
	dbgprint("=============GetSlcWordlinePageMask start================")

	local PageMaskLen = ALLOC_SPACE(PageCount, 8)
	local RetPageMask = btnew(PageMaskLen, 0)
	local PageArray = {}

	for page=0, PageCount-1 do
		byte = btget(PageMask, math.floor(page / 8))
		if band(byte, ls(1, math.fmod(page, 8))) ~= 0 then
			PageArray[page] = page
			--dbgprint("PageArray:"..page)
		end
	end

	for wl=1, wlcount do
		bGoodWL = true
		if TBL_ORDER[wl][1] ~= -1 then
			if PageArray[TBL_ORDER[wl][1]] == nil then
				bGoodWL = false
				--dbgprint("wl"..(wl-1).." at page:"..TBL_ORDER[wl][1].." is broken")
			end
		end

		if bGoodWL then
			setbitvalue(RetPageMask, wl-1, 1)
		end
	end

	dbgprint("=============end================")

	return wlcount, RetPageMask
end

function GetNormalPageMask(PageMask, PageCount)
	dbgprint("=============GetNormalPageMask start================")
	local PageMaskLen = ALLOC_SPACE(PageCount, 8)
	local RetPageMask = btnew(PageMaskLen, 0)
	local nRet = 0

	for wl=0, wlcount-1 do
		byte = btget(PageMask, math.floor(wl / 8))
		if band(byte, ls(1, math.fmod(wl, 8))) ~= 0 then
			for i=1, cellNum do
				if TBL_WORDLINE[wl+1][i] ~= -1 then
					setbitvalue(RetPageMask, TBL_WORDLINE[wl+1][i], 1)
					nRet = nRet + 1
				end
			end
		end
	end


	dbgprint("=============end================")
	return nRet, RetPageMask
end

function GetSlcNormalPageMask(PageMask, PageCount)
	dbgprint("=============GetSlcNormalPageMask start================")
	local PageMaskLen = ALLOC_SPACE(PageCount, 8)
	local RetPageMask = btnew(PageMaskLen, 0)
	local nRet = 0

	for wl=0, wlcount-1 do
		byte = btget(PageMask, math.floor(wl / 8))
		if band(byte, ls(1, math.fmod(wl, 8))) ~= 0 then
			setbitvalue(RetPageMask, TBL_ORDER[wl+1][1], 1)
			nRet = nRet + 1
		end
	end


	dbgprint("=============end================")
	return nRet, RetPageMask
end

--[[
function OrderPage2ProgramPage(nAddr, nPhyPage)
	local page = math.fmod(nAddr, nPhyPage)
	local wl = GetWLOfOrder(page)
	if wl == -1 then
		return -1
	end

	return math.floor(nAddr / nPhyPage) * nPhyPage + TBL_WORDLINE[wl][1]
end

function ProgramPage2OrderPage(nAddr, nPhyPage)
	local page = math.fmod(nAddr, nPhyPage)
	if not IsAInOrder(page) then
		return -1
	end

	local wl = GetWLOfPage(page)
	if wl == -1 then
		return -1
	end

	return math.floor(nAddr / nPhyPage) * nPhyPage + TBL_ORDER[wl][1]
end
]]
