// Code generated by go-swagger; DO NOT EDIT.

// Copyright 2018 The go-netbox Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package extras

// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command

import (
	"github.com/go-openapi/runtime"

	strfmt "github.com/go-openapi/strfmt"
)

// New creates a new extras API client.
func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client {
	return &Client{transport: transport, formats: formats}
}

/*
Client for extras API
*/
type Client struct {
	transport runtime.ClientTransport
	formats   strfmt.Registry
}

/*
ExtrasChoicesList extras choices list API
*/
func (a *Client) ExtrasChoicesList(params *ExtrasChoicesListParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasChoicesListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasChoicesListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras__choices_list",
		Method:             "GET",
		PathPattern:        "/extras/_choices/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasChoicesListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasChoicesListOK), nil

}

/*
ExtrasChoicesRead extras choices read API
*/
func (a *Client) ExtrasChoicesRead(params *ExtrasChoicesReadParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasChoicesReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasChoicesReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras__choices_read",
		Method:             "GET",
		PathPattern:        "/extras/_choices/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasChoicesReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasChoicesReadOK), nil

}

/*
ExtrasExportTemplatesCreate extras export templates create API
*/
func (a *Client) ExtrasExportTemplatesCreate(params *ExtrasExportTemplatesCreateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasExportTemplatesCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasExportTemplatesCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_export-templates_create",
		Method:             "POST",
		PathPattern:        "/extras/export-templates/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasExportTemplatesCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasExportTemplatesCreateCreated), nil

}

/*
ExtrasExportTemplatesDelete extras export templates delete API
*/
func (a *Client) ExtrasExportTemplatesDelete(params *ExtrasExportTemplatesDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasExportTemplatesDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasExportTemplatesDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_export-templates_delete",
		Method:             "DELETE",
		PathPattern:        "/extras/export-templates/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasExportTemplatesDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasExportTemplatesDeleteNoContent), nil

}

/*
ExtrasExportTemplatesList extras export templates list API
*/
func (a *Client) ExtrasExportTemplatesList(params *ExtrasExportTemplatesListParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasExportTemplatesListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasExportTemplatesListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_export-templates_list",
		Method:             "GET",
		PathPattern:        "/extras/export-templates/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasExportTemplatesListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasExportTemplatesListOK), nil

}

/*
ExtrasExportTemplatesPartialUpdate extras export templates partial update API
*/
func (a *Client) ExtrasExportTemplatesPartialUpdate(params *ExtrasExportTemplatesPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasExportTemplatesPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasExportTemplatesPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_export-templates_partial_update",
		Method:             "PATCH",
		PathPattern:        "/extras/export-templates/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasExportTemplatesPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasExportTemplatesPartialUpdateOK), nil

}

/*
ExtrasExportTemplatesRead extras export templates read API
*/
func (a *Client) ExtrasExportTemplatesRead(params *ExtrasExportTemplatesReadParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasExportTemplatesReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasExportTemplatesReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_export-templates_read",
		Method:             "GET",
		PathPattern:        "/extras/export-templates/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasExportTemplatesReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasExportTemplatesReadOK), nil

}

/*
ExtrasExportTemplatesUpdate extras export templates update API
*/
func (a *Client) ExtrasExportTemplatesUpdate(params *ExtrasExportTemplatesUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasExportTemplatesUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasExportTemplatesUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_export-templates_update",
		Method:             "PUT",
		PathPattern:        "/extras/export-templates/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasExportTemplatesUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasExportTemplatesUpdateOK), nil

}

/*
ExtrasGraphsCreate extras graphs create API
*/
func (a *Client) ExtrasGraphsCreate(params *ExtrasGraphsCreateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasGraphsCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasGraphsCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_graphs_create",
		Method:             "POST",
		PathPattern:        "/extras/graphs/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasGraphsCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasGraphsCreateCreated), nil

}

/*
ExtrasGraphsDelete extras graphs delete API
*/
func (a *Client) ExtrasGraphsDelete(params *ExtrasGraphsDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasGraphsDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasGraphsDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_graphs_delete",
		Method:             "DELETE",
		PathPattern:        "/extras/graphs/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasGraphsDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasGraphsDeleteNoContent), nil

}

/*
ExtrasGraphsList extras graphs list API
*/
func (a *Client) ExtrasGraphsList(params *ExtrasGraphsListParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasGraphsListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasGraphsListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_graphs_list",
		Method:             "GET",
		PathPattern:        "/extras/graphs/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasGraphsListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasGraphsListOK), nil

}

/*
ExtrasGraphsPartialUpdate extras graphs partial update API
*/
func (a *Client) ExtrasGraphsPartialUpdate(params *ExtrasGraphsPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasGraphsPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasGraphsPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_graphs_partial_update",
		Method:             "PATCH",
		PathPattern:        "/extras/graphs/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasGraphsPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasGraphsPartialUpdateOK), nil

}

/*
ExtrasGraphsRead extras graphs read API
*/
func (a *Client) ExtrasGraphsRead(params *ExtrasGraphsReadParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasGraphsReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasGraphsReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_graphs_read",
		Method:             "GET",
		PathPattern:        "/extras/graphs/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasGraphsReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasGraphsReadOK), nil

}

/*
ExtrasGraphsUpdate extras graphs update API
*/
func (a *Client) ExtrasGraphsUpdate(params *ExtrasGraphsUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasGraphsUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasGraphsUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_graphs_update",
		Method:             "PUT",
		PathPattern:        "/extras/graphs/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasGraphsUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasGraphsUpdateOK), nil

}

/*
ExtrasImageAttachmentsCreate extras image attachments create API
*/
func (a *Client) ExtrasImageAttachmentsCreate(params *ExtrasImageAttachmentsCreateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasImageAttachmentsCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasImageAttachmentsCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_image-attachments_create",
		Method:             "POST",
		PathPattern:        "/extras/image-attachments/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasImageAttachmentsCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasImageAttachmentsCreateCreated), nil

}

/*
ExtrasImageAttachmentsDelete extras image attachments delete API
*/
func (a *Client) ExtrasImageAttachmentsDelete(params *ExtrasImageAttachmentsDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasImageAttachmentsDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasImageAttachmentsDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_image-attachments_delete",
		Method:             "DELETE",
		PathPattern:        "/extras/image-attachments/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasImageAttachmentsDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasImageAttachmentsDeleteNoContent), nil

}

/*
ExtrasImageAttachmentsList extras image attachments list API
*/
func (a *Client) ExtrasImageAttachmentsList(params *ExtrasImageAttachmentsListParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasImageAttachmentsListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasImageAttachmentsListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_image-attachments_list",
		Method:             "GET",
		PathPattern:        "/extras/image-attachments/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasImageAttachmentsListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasImageAttachmentsListOK), nil

}

/*
ExtrasImageAttachmentsPartialUpdate extras image attachments partial update API
*/
func (a *Client) ExtrasImageAttachmentsPartialUpdate(params *ExtrasImageAttachmentsPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasImageAttachmentsPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasImageAttachmentsPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_image-attachments_partial_update",
		Method:             "PATCH",
		PathPattern:        "/extras/image-attachments/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasImageAttachmentsPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasImageAttachmentsPartialUpdateOK), nil

}

/*
ExtrasImageAttachmentsRead extras image attachments read API
*/
func (a *Client) ExtrasImageAttachmentsRead(params *ExtrasImageAttachmentsReadParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasImageAttachmentsReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasImageAttachmentsReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_image-attachments_read",
		Method:             "GET",
		PathPattern:        "/extras/image-attachments/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasImageAttachmentsReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasImageAttachmentsReadOK), nil

}

/*
ExtrasImageAttachmentsUpdate extras image attachments update API
*/
func (a *Client) ExtrasImageAttachmentsUpdate(params *ExtrasImageAttachmentsUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasImageAttachmentsUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasImageAttachmentsUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_image-attachments_update",
		Method:             "PUT",
		PathPattern:        "/extras/image-attachments/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasImageAttachmentsUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasImageAttachmentsUpdateOK), nil

}

/*
ExtrasRecentActivityList List all UserActions to provide a log of recent activity.
*/
func (a *Client) ExtrasRecentActivityList(params *ExtrasRecentActivityListParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasRecentActivityListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasRecentActivityListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_recent-activity_list",
		Method:             "GET",
		PathPattern:        "/extras/recent-activity/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasRecentActivityListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasRecentActivityListOK), nil

}

/*
ExtrasRecentActivityRead List all UserActions to provide a log of recent activity.
*/
func (a *Client) ExtrasRecentActivityRead(params *ExtrasRecentActivityReadParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasRecentActivityReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasRecentActivityReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_recent-activity_read",
		Method:             "GET",
		PathPattern:        "/extras/recent-activity/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasRecentActivityReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasRecentActivityReadOK), nil

}

/*
ExtrasTopologyMapsCreate extras topology maps create API
*/
func (a *Client) ExtrasTopologyMapsCreate(params *ExtrasTopologyMapsCreateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasTopologyMapsCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasTopologyMapsCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_topology-maps_create",
		Method:             "POST",
		PathPattern:        "/extras/topology-maps/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasTopologyMapsCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasTopologyMapsCreateCreated), nil

}

/*
ExtrasTopologyMapsDelete extras topology maps delete API
*/
func (a *Client) ExtrasTopologyMapsDelete(params *ExtrasTopologyMapsDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasTopologyMapsDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasTopologyMapsDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_topology-maps_delete",
		Method:             "DELETE",
		PathPattern:        "/extras/topology-maps/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasTopologyMapsDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasTopologyMapsDeleteNoContent), nil

}

/*
ExtrasTopologyMapsList extras topology maps list API
*/
func (a *Client) ExtrasTopologyMapsList(params *ExtrasTopologyMapsListParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasTopologyMapsListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasTopologyMapsListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_topology-maps_list",
		Method:             "GET",
		PathPattern:        "/extras/topology-maps/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasTopologyMapsListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasTopologyMapsListOK), nil

}

/*
ExtrasTopologyMapsPartialUpdate extras topology maps partial update API
*/
func (a *Client) ExtrasTopologyMapsPartialUpdate(params *ExtrasTopologyMapsPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasTopologyMapsPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasTopologyMapsPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_topology-maps_partial_update",
		Method:             "PATCH",
		PathPattern:        "/extras/topology-maps/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasTopologyMapsPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasTopologyMapsPartialUpdateOK), nil

}

/*
ExtrasTopologyMapsRead extras topology maps read API
*/
func (a *Client) ExtrasTopologyMapsRead(params *ExtrasTopologyMapsReadParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasTopologyMapsReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasTopologyMapsReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_topology-maps_read",
		Method:             "GET",
		PathPattern:        "/extras/topology-maps/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasTopologyMapsReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasTopologyMapsReadOK), nil

}

/*
ExtrasTopologyMapsRender extras topology maps render API
*/
func (a *Client) ExtrasTopologyMapsRender(params *ExtrasTopologyMapsRenderParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasTopologyMapsRenderOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasTopologyMapsRenderParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_topology-maps_render",
		Method:             "GET",
		PathPattern:        "/extras/topology-maps/{id}/render/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasTopologyMapsRenderReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasTopologyMapsRenderOK), nil

}

/*
ExtrasTopologyMapsUpdate extras topology maps update API
*/
func (a *Client) ExtrasTopologyMapsUpdate(params *ExtrasTopologyMapsUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*ExtrasTopologyMapsUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewExtrasTopologyMapsUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "extras_topology-maps_update",
		Method:             "PUT",
		PathPattern:        "/extras/topology-maps/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &ExtrasTopologyMapsUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*ExtrasTopologyMapsUpdateOK), nil

}

// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
	a.transport = transport
}
