package obsws

import (
	"errors"
	"time"
)

// This file is automatically generated.
// https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py

// GetTransitionListRequest : List of all transitions available in the frontend's dropdown menu.
//
// Since obs-websocket version: 4.1.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionlist
type GetTransitionListRequest struct {
	_request `json:",squash"`
	response chan GetTransitionListResponse
}

// NewGetTransitionListRequest returns a new GetTransitionListRequest.
func NewGetTransitionListRequest() GetTransitionListRequest {
	return GetTransitionListRequest{
		_request{
			ID_:   GetMessageID(),
			Type_: "GetTransitionList",
			err:   make(chan error, 1),
		},
		make(chan GetTransitionListResponse, 1),
	}
}

// Send sends the request.
func (r *GetTransitionListRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp GetTransitionListResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r GetTransitionListRequest) Receive() (GetTransitionListResponse, error) {
	if !r.sent {
		return GetTransitionListResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetTransitionListResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetTransitionListResponse{}, err
		case <-time.After(receiveTimeout):
			return GetTransitionListResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r GetTransitionListRequest) SendReceive(c Client) (GetTransitionListResponse, error) {
	if err := r.Send(c); err != nil {
		return GetTransitionListResponse{}, err
	}
	return r.Receive()
}

// GetTransitionListResponse : Response for GetTransitionListRequest.
//
// Since obs-websocket version: 4.1.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionlist
type GetTransitionListResponse struct {
	// Name of the currently active transition.
	// Required: Yes.
	CurrentTransition string `json:"current-transition"`
	// List of transitions.
	// Required: Yes.
	Transitions []map[string]interface{} `json:"transitions"`
	// Name of the transition.
	// Required: Yes.
	TransitionsName string `json:"transitions.*.name"`
	_response       `json:",squash"`
}

// GetCurrentTransitionRequest : Get the name of the currently selected transition in the frontend's dropdown menu.
//
// Since obs-websocket version: 0.3.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getcurrenttransition
type GetCurrentTransitionRequest struct {
	_request `json:",squash"`
	response chan GetCurrentTransitionResponse
}

// NewGetCurrentTransitionRequest returns a new GetCurrentTransitionRequest.
func NewGetCurrentTransitionRequest() GetCurrentTransitionRequest {
	return GetCurrentTransitionRequest{
		_request{
			ID_:   GetMessageID(),
			Type_: "GetCurrentTransition",
			err:   make(chan error, 1),
		},
		make(chan GetCurrentTransitionResponse, 1),
	}
}

// Send sends the request.
func (r *GetCurrentTransitionRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp GetCurrentTransitionResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r GetCurrentTransitionRequest) Receive() (GetCurrentTransitionResponse, error) {
	if !r.sent {
		return GetCurrentTransitionResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetCurrentTransitionResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetCurrentTransitionResponse{}, err
		case <-time.After(receiveTimeout):
			return GetCurrentTransitionResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r GetCurrentTransitionRequest) SendReceive(c Client) (GetCurrentTransitionResponse, error) {
	if err := r.Send(c); err != nil {
		return GetCurrentTransitionResponse{}, err
	}
	return r.Receive()
}

// GetCurrentTransitionResponse : Response for GetCurrentTransitionRequest.
//
// Since obs-websocket version: 0.3.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getcurrenttransition
type GetCurrentTransitionResponse struct {
	// Name of the selected transition.
	// Required: Yes.
	Name string `json:"name"`
	// Transition duration (in milliseconds) if supported by the transition.
	// Required: No.
	Duration  int `json:"duration"`
	_response `json:",squash"`
}

// SetCurrentTransitionRequest : Set the active transition.
//
// Since obs-websocket version: 0.3.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setcurrenttransition
type SetCurrentTransitionRequest struct {
	// The name of the transition.
	// Required: Yes.
	TransitionName string `json:"transition-name"`
	_request       `json:",squash"`
	response       chan SetCurrentTransitionResponse
}

// NewSetCurrentTransitionRequest returns a new SetCurrentTransitionRequest.
func NewSetCurrentTransitionRequest(transitionName string) SetCurrentTransitionRequest {
	return SetCurrentTransitionRequest{
		transitionName,
		_request{
			ID_:   GetMessageID(),
			Type_: "SetCurrentTransition",
			err:   make(chan error, 1),
		},
		make(chan SetCurrentTransitionResponse, 1),
	}
}

// Send sends the request.
func (r *SetCurrentTransitionRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp SetCurrentTransitionResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r SetCurrentTransitionRequest) Receive() (SetCurrentTransitionResponse, error) {
	if !r.sent {
		return SetCurrentTransitionResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return SetCurrentTransitionResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return SetCurrentTransitionResponse{}, err
		case <-time.After(receiveTimeout):
			return SetCurrentTransitionResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r SetCurrentTransitionRequest) SendReceive(c Client) (SetCurrentTransitionResponse, error) {
	if err := r.Send(c); err != nil {
		return SetCurrentTransitionResponse{}, err
	}
	return r.Receive()
}

// SetCurrentTransitionResponse : Response for SetCurrentTransitionRequest.
//
// Since obs-websocket version: 0.3.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setcurrenttransition
type SetCurrentTransitionResponse struct {
	_response `json:",squash"`
}

// SetTransitionDurationRequest : Set the duration of the currently selected transition if supported.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#settransitionduration
type SetTransitionDurationRequest struct {
	// Desired duration of the transition (in milliseconds).
	// Required: Yes.
	Duration int `json:"duration"`
	_request `json:",squash"`
	response chan SetTransitionDurationResponse
}

// NewSetTransitionDurationRequest returns a new SetTransitionDurationRequest.
func NewSetTransitionDurationRequest(duration int) SetTransitionDurationRequest {
	return SetTransitionDurationRequest{
		duration,
		_request{
			ID_:   GetMessageID(),
			Type_: "SetTransitionDuration",
			err:   make(chan error, 1),
		},
		make(chan SetTransitionDurationResponse, 1),
	}
}

// Send sends the request.
func (r *SetTransitionDurationRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp SetTransitionDurationResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r SetTransitionDurationRequest) Receive() (SetTransitionDurationResponse, error) {
	if !r.sent {
		return SetTransitionDurationResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return SetTransitionDurationResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return SetTransitionDurationResponse{}, err
		case <-time.After(receiveTimeout):
			return SetTransitionDurationResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r SetTransitionDurationRequest) SendReceive(c Client) (SetTransitionDurationResponse, error) {
	if err := r.Send(c); err != nil {
		return SetTransitionDurationResponse{}, err
	}
	return r.Receive()
}

// SetTransitionDurationResponse : Response for SetTransitionDurationRequest.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#settransitionduration
type SetTransitionDurationResponse struct {
	_response `json:",squash"`
}

// GetTransitionDurationRequest : Get the duration of the currently selected transition if supported.
//
// Since obs-websocket version: 4.1.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionduration
type GetTransitionDurationRequest struct {
	_request `json:",squash"`
	response chan GetTransitionDurationResponse
}

// NewGetTransitionDurationRequest returns a new GetTransitionDurationRequest.
func NewGetTransitionDurationRequest() GetTransitionDurationRequest {
	return GetTransitionDurationRequest{
		_request{
			ID_:   GetMessageID(),
			Type_: "GetTransitionDuration",
			err:   make(chan error, 1),
		},
		make(chan GetTransitionDurationResponse, 1),
	}
}

// Send sends the request.
func (r *GetTransitionDurationRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp GetTransitionDurationResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r GetTransitionDurationRequest) Receive() (GetTransitionDurationResponse, error) {
	if !r.sent {
		return GetTransitionDurationResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetTransitionDurationResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetTransitionDurationResponse{}, err
		case <-time.After(receiveTimeout):
			return GetTransitionDurationResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r GetTransitionDurationRequest) SendReceive(c Client) (GetTransitionDurationResponse, error) {
	if err := r.Send(c); err != nil {
		return GetTransitionDurationResponse{}, err
	}
	return r.Receive()
}

// GetTransitionDurationResponse : Response for GetTransitionDurationRequest.
//
// Since obs-websocket version: 4.1.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionduration
type GetTransitionDurationResponse struct {
	// Duration of the current transition (in milliseconds).
	// Required: Yes.
	TransitionDuration int `json:"transition-duration"`
	_response          `json:",squash"`
}
