package tools
import (
"fmt"
"os"
"strings"
"skraak/utils"
)
type CallsShowImagesInput struct {
DataFilePath string `json:"data_file_path"`
Color bool `json:"color"`
ImageSize int `json:"image_size"`
Sixel bool `json:"sixel"`
ITerm bool `json:"iterm"`
}
type CallsShowImagesOutput struct {
SegmentsShown int `json:"segments_shown"`
WavFile string `json:"wav_file"`
Error string `json:"error,omitempty"`
}
func CallsShowImages(input CallsShowImagesInput) (CallsShowImagesOutput, error) {
var output CallsShowImagesOutput
if _, err := os.Stat(input.DataFilePath); os.IsNotExist(err) {
output.Error = fmt.Sprintf("File not found: %s", input.DataFilePath)
return output, fmt.Errorf("%s", output.Error)
}
wavPath := strings.TrimSuffix(input.DataFilePath, ".data")
output.WavFile = wavPath
if _, err := os.Stat(wavPath); os.IsNotExist(err) {
output.Error = fmt.Sprintf("WAV file not found: %s", wavPath)
return output, fmt.Errorf("%s", output.Error)
}
dataFile, err := utils.ParseDataFile(input.DataFilePath)
if err != nil {
output.Error = err.Error()
return output, fmt.Errorf("%s", output.Error)
}
if len(dataFile.Segments) == 0 {
output.Error = "No segments found in .data file"
return output, fmt.Errorf("%s", output.Error)
}
imgSize := input.ImageSize
if imgSize == 0 {
imgSize = utils.SpectrogramDisplaySize
}
protocol := utils.ProtocolKitty
if input.ITerm {
protocol = utils.ProtocolITerm
} else if input.Sixel {
protocol = utils.ProtocolSixel
}
for i, seg := range dataFile.Segments {
img, err := utils.GenerateSegmentSpectrogram(input.DataFilePath, seg.StartTime, seg.EndTime, input.Color, imgSize)
if err != nil || img == nil {
continue
}
labelInfo := formatSegmentLabels(seg.Labels)
fmt.Fprintf(os.Stderr, "Segment %d: %.1fs - %.1fs (%.1fs)%s\n",
i+1, seg.StartTime, seg.EndTime, seg.EndTime-seg.StartTime, labelInfo)
if err := utils.WriteImage(img, os.Stdout, protocol); err != nil {
output.Error = fmt.Sprintf("Failed to write image: %v", err)
return output, fmt.Errorf("%s", output.Error)
}
fmt.Println() }
output.SegmentsShown = len(dataFile.Segments)
return output, nil
}
func formatSegmentLabels(labels []*utils.Label) string {
if len(labels) == 0 {
return ""
}
var parts []string
for _, l := range labels {
part := l.Species
if l.CallType != "" {
part += "/" + l.CallType
}
if l.Filter != "" {
part += " [" + l.Filter + "]"
}
parts = append(parts, part)
}
return " " + strings.Join(parts, ", ")
}