package brotli

var kInsBase = []uint32{
	0,
	1,
	2,
	3,
	4,
	5,
	6,
	8,
	10,
	14,
	18,
	26,
	34,
	50,
	66,
	98,
	130,
	194,
	322,
	578,
	1090,
	2114,
	6210,
	22594,
}

var kInsExtra = []uint32{
	0,
	0,
	0,
	0,
	0,
	0,
	1,
	1,
	2,
	2,
	3,
	3,
	4,
	4,
	5,
	5,
	6,
	7,
	8,
	9,
	10,
	12,
	14,
	24,
}

var kCopyBase = []uint32{
	2,
	3,
	4,
	5,
	6,
	7,
	8,
	9,
	10,
	12,
	14,
	18,
	22,
	30,
	38,
	54,
	70,
	102,
	134,
	198,
	326,
	582,
	1094,
	2118,
}

var kCopyExtra = []uint32{
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	1,
	1,
	2,
	2,
	3,
	3,
	4,
	4,
	5,
	5,
	6,
	7,
	8,
	9,
	10,
	24,
}

func getInsertLengthCode( uint) uint16 {
	if  < 6 {
		return uint16()
	} else if  < 130 {
		var  uint32 = log2FloorNonZero(-2) - 1
		return uint16(( << 1) + uint32((-2)>>) + 2)
	} else if  < 2114 {
		return uint16(log2FloorNonZero(-66) + 10)
	} else if  < 6210 {
		return 21
	} else if  < 22594 {
		return 22
	} else {
		return 23
	}
}

func getCopyLengthCode( uint) uint16 {
	if  < 10 {
		return uint16( - 2)
	} else if  < 134 {
		var  uint32 = log2FloorNonZero(-6) - 1
		return uint16(( << 1) + uint32((-6)>>) + 4)
	} else if  < 2118 {
		return uint16(log2FloorNonZero(-70) + 12)
	} else {
		return 23
	}
}

func combineLengthCodes( uint16,  uint16,  bool) uint16 {
	var  uint16 = uint16(&0x7 | (&0x7)<<3)
	if  &&  < 8 &&  < 16 {
		if  < 8 {
			return 
		} else {
			return  | 64
		}
	} else {
		/* Specification: 5 Encoding of ... (last table) */
		/* offset = 2 * index, where index is in range [0..8] */
		var  uint32 = 2 * ((uint32() >> 3) + 3*(uint32()>>3))

		/* All values in specification are K * 64,
		   where   K = [2, 3, 6, 4, 5, 8, 7, 9, 10],
		       i + 1 = [1, 2, 3, 4, 5, 6, 7, 8,  9],
		   K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1,  2] = D.
		   All values in D require only 2 bits to encode.
		   Magic constant is shifted 6 bits left, to avoid final multiplication. */
		 = ( << 5) + 0x40 + ((0x520D40 >> ) & 0xC0)

		return uint16( | uint32())
	}
}

func getLengthCode( uint,  uint,  bool,  *uint16) {
	var  uint16 = getInsertLengthCode()
	var  uint16 = getCopyLengthCode()
	* = combineLengthCodes(, , )
}

func getInsertBase( uint16) uint32 {
	return kInsBase[]
}

func getInsertExtra( uint16) uint32 {
	return kInsExtra[]
}

func getCopyBase( uint16) uint32 {
	return kCopyBase[]
}

func getCopyExtra( uint16) uint32 {
	return kCopyExtra[]
}

type command struct {
	insert_len_  uint32
	copy_len_    uint32
	dist_extra_  uint32
	cmd_prefix_  uint16
	dist_prefix_ uint16
}

/* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */
func makeCommand( *distanceParams,  uint,  uint,  int,  uint) ( command) {
	/* Don't rely on signed int representation, use honest casts. */
	var  uint32 = uint32(byte(int8()))
	.insert_len_ = uint32()
	.copy_len_ = uint32(uint32() | <<25)

	/* The distance prefix and extra bits are stored in this Command as if
	   npostfix and ndirect were 0, they are only recomputed later after the
	   clustering if needed. */
	prefixEncodeCopyDistance(, uint(.num_direct_distance_codes), uint(.distance_postfix_bits), &.dist_prefix_, &.dist_extra_)
	getLengthCode(, uint(int()+), (.dist_prefix_&0x3FF == 0), &.cmd_prefix_)

	return 
}

func makeInsertCommand( uint) ( command) {
	.insert_len_ = uint32()
	.copy_len_ = 4 << 25
	.dist_extra_ = 0
	.dist_prefix_ = numDistanceShortCodes
	getLengthCode(, 4, false, &.cmd_prefix_)
	return 
}

func commandRestoreDistanceCode( *command,  *distanceParams) uint32 {
	if uint32(.dist_prefix_&0x3FF) < numDistanceShortCodes+.num_direct_distance_codes {
		return uint32(.dist_prefix_) & 0x3FF
	} else {
		var  uint32 = uint32(.dist_prefix_) & 0x3FF
		var  uint32 = uint32(.dist_prefix_) >> 10
		var  uint32 = .dist_extra_
		var  uint32 = (1 << .distance_postfix_bits) - 1
		var  uint32 = ( - .num_direct_distance_codes - numDistanceShortCodes) >> .distance_postfix_bits
		var  uint32 = ( - .num_direct_distance_codes - numDistanceShortCodes) & 
		var  uint32 = ((2 + ( & 1)) << ) - 4
		return (( + ) << .distance_postfix_bits) +  + .num_direct_distance_codes + numDistanceShortCodes
	}
}

func commandDistanceContext( *command) uint32 {
	var  uint32 = uint32(.cmd_prefix_) >> 6
	var  uint32 = uint32(.cmd_prefix_) & 7
	if ( == 0 ||  == 2 ||  == 4 ||  == 7) && ( <= 2) {
		return 
	}

	return 3
}

func commandCopyLen( *command) uint32 {
	return .copy_len_ & 0x1FFFFFF
}

func commandCopyLenCode( *command) uint32 {
	var  uint32 = .copy_len_ >> 25
	var  int32 = int32(int8(byte( | (&0x40)<<1)))
	return uint32(int32(.copy_len_&0x1FFFFFF) + )
}