/*
DESCRIPTION
  device.go provides AVDevice, an interface that describes a configurable
  audio or video device that can be started and stopped from which data may
  be obtained.

AUTHORS
  Saxon A. Nelson-Milton <saxon@ausocean.org>

LICENSE
  Copyright (C) 2019 the Australian Ocean Lab (AusOcean)

  It is free software: you can redistribute it and/or modify them
  under the terms of the GNU General Public License as published by the
  Free Software Foundation, either version 3 of the License, or (at your
  option) any later version.

  It is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  for more details.

  You should have received a copy of the GNU General Public License
  in gpl.txt.  If not, see http://www.gnu.org/licenses.
*/

// Package device provides an interface and implementations for input devices
// that can be started and stopped from which media data can be obtained.
package device

import (
	"fmt"
	"io"

	"bitbucket.org/ausocean/av/revid/config"
)

// AVDevice describes a configurable audio or video device from which media data
// can be obtained. AVDevice is an io.Reader.
type AVDevice interface {
	io.Reader

	// Name returns the name of the AVDevice.
	Name() string

	// Set allows for configuration of the AVDevice using a Config struct. All,
	// some or none of the fields of the Config struct may be used for configuration
	// by an implementation. An implementation should specify what fields are
	// considered.
	Set(c config.Config) error

	// Start will start the AVDevice capturing media data; after which the Read
	// method may be called to obtain the data. The format of the data may differ
	// and should be specified by the implementation.
	Start() error

	// Stop will stop the AVDevice from capturing media data. From this point
	// Reads will no longer be successful.
	Stop() error

	// IsRunning is used to determine if the device is running.
	IsRunning() bool
}

// multiError implements the built in error interface. multiError is used here
// to collect multi errors during validation of configruation parameters for o
// AVDevices.
type MultiError []error

func (me MultiError) Error() string {
	return fmt.Sprintf("%v", []error(me))
}