package pgtype

import (
	
	
	
	
	
	

	
)

type BoxScanner interface {
	ScanBox(v Box) error
}

type BoxValuer interface {
	BoxValue() (Box, error)
}

type Box struct {
	P     [2]Vec2
	Valid bool
}

func ( *Box) ( Box) error {
	* = 
	return nil
}

func ( Box) () (Box, error) {
	return , nil
}

// Scan implements the database/sql Scanner interface.
func ( *Box) ( any) error {
	if  == nil {
		* = Box{}
		return nil
	}

	switch src := .(type) {
	case string:
		return scanPlanTextAnyToBoxScanner{}.Scan([]byte(), )
	}

	return fmt.Errorf("cannot scan %T", )
}

// Value implements the database/sql/driver Valuer interface.
func ( Box) () (driver.Value, error) {
	if !.Valid {
		return nil, nil
	}

	,  := BoxCodec{}.PlanEncode(nil, 0, TextFormatCode, ).Encode(, nil)
	if  != nil {
		return nil, 
	}
	return string(), 
}

type BoxCodec struct{}

func (BoxCodec) ( int16) bool {
	return  == TextFormatCode ||  == BinaryFormatCode
}

func (BoxCodec) () int16 {
	return BinaryFormatCode
}

func (BoxCodec) ( *Map,  uint32,  int16,  any) EncodePlan {
	if ,  := .(BoxValuer); ! {
		return nil
	}

	switch  {
	case BinaryFormatCode:
		return encodePlanBoxCodecBinary{}
	case TextFormatCode:
		return encodePlanBoxCodecText{}
	}

	return nil
}

type encodePlanBoxCodecBinary struct{}

func (encodePlanBoxCodecBinary) ( any,  []byte) ( []byte,  error) {
	,  := .(BoxValuer).BoxValue()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	 = pgio.AppendUint64(, math.Float64bits(.P[0].X))
	 = pgio.AppendUint64(, math.Float64bits(.P[0].Y))
	 = pgio.AppendUint64(, math.Float64bits(.P[1].X))
	 = pgio.AppendUint64(, math.Float64bits(.P[1].Y))
	return , nil
}

type encodePlanBoxCodecText struct{}

func (encodePlanBoxCodecText) ( any,  []byte) ( []byte,  error) {
	,  := .(BoxValuer).BoxValue()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	 = append(, fmt.Sprintf(`(%s,%s),(%s,%s)`,
		strconv.FormatFloat(.P[0].X, 'f', -1, 64),
		strconv.FormatFloat(.P[0].Y, 'f', -1, 64),
		strconv.FormatFloat(.P[1].X, 'f', -1, 64),
		strconv.FormatFloat(.P[1].Y, 'f', -1, 64),
	)...)
	return , nil
}

func (BoxCodec) ( *Map,  uint32,  int16,  any) ScanPlan {

	switch  {
	case BinaryFormatCode:
		switch .(type) {
		case BoxScanner:
			return scanPlanBinaryBoxToBoxScanner{}
		}
	case TextFormatCode:
		switch .(type) {
		case BoxScanner:
			return scanPlanTextAnyToBoxScanner{}
		}
	}

	return nil
}

type scanPlanBinaryBoxToBoxScanner struct{}

func (scanPlanBinaryBoxToBoxScanner) ( []byte,  any) error {
	 := ().(BoxScanner)

	if  == nil {
		return .ScanBox(Box{})
	}

	if len() != 32 {
		return fmt.Errorf("invalid length for Box: %v", len())
	}

	 := binary.BigEndian.Uint64()
	 := binary.BigEndian.Uint64([8:])
	 := binary.BigEndian.Uint64([16:])
	 := binary.BigEndian.Uint64([24:])

	return .ScanBox(Box{
		P: [2]Vec2{
			{math.Float64frombits(), math.Float64frombits()},
			{math.Float64frombits(), math.Float64frombits()},
		},
		Valid: true,
	})
}

type scanPlanTextAnyToBoxScanner struct{}

func (scanPlanTextAnyToBoxScanner) ( []byte,  any) error {
	 := ().(BoxScanner)

	if  == nil {
		return .ScanBox(Box{})
	}

	if len() < 11 {
		return fmt.Errorf("invalid length for Box: %v", len())
	}

	 := string([1:])

	var  int
	 = strings.IndexByte(, ',')

	,  := strconv.ParseFloat([:], 64)
	if  != nil {
		return 
	}

	 = [+1:]
	 = strings.IndexByte(, ')')

	,  := strconv.ParseFloat([:], 64)
	if  != nil {
		return 
	}

	 = [+3:]
	 = strings.IndexByte(, ',')

	,  := strconv.ParseFloat([:], 64)
	if  != nil {
		return 
	}

	 = [+1 : len()-1]

	,  := strconv.ParseFloat(, 64)
	if  != nil {
		return 
	}

	return .ScanBox(Box{P: [2]Vec2{{, }, {, }}, Valid: true})
}

func ( BoxCodec) ( *Map,  uint32,  int16,  []byte) (driver.Value, error) {
	return codecDecodeToTextFormat(, , , , )
}

func ( BoxCodec) ( *Map,  uint32,  int16,  []byte) (any, error) {
	if  == nil {
		return nil, nil
	}

	var  Box
	 := codecScan(, , , , , &)
	if  != nil {
		return nil, 
	}
	return , nil
}