package d2isometricimg

import (
	
	
	
	
	

	
	
)

// A capture owns the scene and cached static raster for one bounded export.
// Frame production is serial; neither the input diagram nor caller images are
// retained outside this session. No files or external processes are created.
type capture struct {
	ctx   context.Context
	opts  Options
	scene *nativeScene
	close context.CancelFunc
}

func openCapture( context.Context,  *d2target.Diagram,  Options) (*capture, error) {
	if  == nil {
		 = context.Background()
	}
	if  := .Err();  != nil {
		return nil, 
	}
	,  := context.WithTimeout(, .Timeout)
	,  := d2isometric.BuildScene(, &.Render)
	if  != nil {
		()
		return nil, 
	}
	if  := .Err();  != nil {
		()
		return nil, 
	}
	,  := newNativeSceneWithOptions(, , .Width, .Height, .Assets, .Fonts, nativeSceneOptions{fitContent: .FitContent, camera: .camera, outputDensity: sceneOutputDensity(, .Width, .Height, .camera), links: .LinkBudget})
	if  != nil {
		()
		return nil, fmt.Errorf("initialize native isometric renderer: %w", )
	}
	.Width, .Height = .width, .height
	return &capture{ctx: , opts: , scene: , close: }, nil
}

func ( *capture) ( float64,  bool) (*image.RGBA, error) {
	return .frameImageAt(, , )
}

// Independent packet time lets whole-second authored animations and traffic
// share a seamless GIF loop without changing the public exact-time frame API.
func ( *capture) (,  float64,  bool) (*image.RGBA, error) {
	if  := .ctx.Err();  != nil {
		return nil, 
	}
	,  := .scene.Frame(.ctx, , , )
	if  != nil {
		return nil, fmt.Errorf("render isometric frame at %.4fs: %w", , )
	}
	if  := .ctx.Err();  != nil {
		return nil, 
	}
	if  == nil || .Bounds() != image.Rect(0, 0, .opts.Width, .opts.Height) {
		return nil, fmt.Errorf("native isometric renderer returned unexpected frame bounds")
	}
	return , nil
}

func ( *capture) ( float64,  bool) ([]byte, error) {
	,  := .frameImage(, )
	if  != nil {
		return nil, 
	}
	var  bytes.Buffer
	 := &boundedWriter{ctx: .ctx, w: &, remaining: maxPNGBytes}
	if  := png.Encode(, );  != nil {
		return nil, fmt.Errorf("encode isometric PNG: %w", )
	}
	if  := .ctx.Err();  != nil {
		return nil, 
	}
	return .Bytes(), nil
}