package ini

import (
	
	
	
)

const (
	none = numberFormat(iota)
	binary
	octal
	decimal
	hex
	exponent
)

type numberFormat int
numberHelper is used to dictate what format a number is in and what to do for negative values. Since -1e-4 is a valid number, we cannot just simply check for duplicate negatives.
type numberHelper struct {
	numberFormat numberFormat

	negative         bool
	negativeExponent bool
}

func ( numberHelper) () bool {
	return .numberFormat != none
}

func ( numberHelper) () bool {
	return .negative || .negativeExponent
}

func ( *numberHelper) ( rune) error {
	if .Exists() {
		return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string()))
	}

	switch  {
	case 'b':
		.numberFormat = binary
	case 'o':
		.numberFormat = octal
	case 'x':
		.numberFormat = hex
	case 'e', 'E':
		.numberFormat = exponent
	case '-':
		if .numberFormat != exponent {
			.negative = true
		} else {
			.negativeExponent = true
		}
	case '.':
		.numberFormat = decimal
	default:
		return NewParseError(fmt.Sprintf("invalid number character: %v", string()))
	}

	return nil
}

func ( numberHelper) ( rune) bool {
	switch {
	case .numberFormat == binary:
		if !isBinaryByte() {
			return false
		}
	case .numberFormat == octal:
		if !isOctalByte() {
			return false
		}
	case .numberFormat == hex:
		if !isHexByte() {
			return false
		}
	case .numberFormat == decimal:
		if !isDigit() {
			return false
		}
	case .numberFormat == exponent:
		if !isDigit() {
			return false
		}
	case .negativeExponent:
		if !isDigit() {
			return false
		}
	case .negative:
		if !isDigit() {
			return false
		}
	default:
		if !isDigit() {
			return false
		}
	}

	return true
}

func ( numberHelper) () int {
	switch .numberFormat {
	case binary:
		return 2
	case octal:
		return 8
	case hex:
		return 16
	default:
		return 10
	}
}

func ( numberHelper) () string {
	 := bytes.Buffer{}
	 := 0

	switch .numberFormat {
	case binary:
		++
		.WriteString(strconv.Itoa() + ": binary format\n")
	case octal:
		++
		.WriteString(strconv.Itoa() + ": octal format\n")
	case hex:
		++
		.WriteString(strconv.Itoa() + ": hex format\n")
	case exponent:
		++
		.WriteString(strconv.Itoa() + ": exponent format\n")
	default:
		++
		.WriteString(strconv.Itoa() + ": integer format\n")
	}

	if .negative {
		++
		.WriteString(strconv.Itoa() + ": negative format\n")
	}

	if .negativeExponent {
		++
		.WriteString(strconv.Itoa() + ": negative exponent format\n")
	}

	return .String()