// Copyright 2018 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// AUTO-GENERATED CODE. DO NOT EDIT.

// Package playmoviespartner provides access to the Google Play Movies Partner API.
//
// See https://developers.google.com/playmoviespartner/
//
// Usage example:
//
//   import "google.golang.org/api/playmoviespartner/v1"
//   ...
//   playmoviespartnerService, err := playmoviespartner.New(oauthHttpClient)
package playmoviespartner // import "google.golang.org/api/playmoviespartner/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "playmoviespartner:v1"
const apiName = "playmoviespartner"
const apiVersion = "v1"
const basePath = "https://playmoviespartner.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View the digital assets you publish on Google Play Movies and TV
	PlaymoviesPartnerReadonlyScope = "https://www.googleapis.com/auth/playmovies_partner.readonly"
)

func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Accounts = NewAccountsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Accounts *AccountsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewAccountsService(s *Service) *AccountsService {
	rs := &AccountsService{s: s}
	rs.Avails = NewAccountsAvailsService(s)
	rs.Orders = NewAccountsOrdersService(s)
	rs.StoreInfos = NewAccountsStoreInfosService(s)
	return rs
}

type AccountsService struct {
	s *Service

	Avails *AccountsAvailsService

	Orders *AccountsOrdersService

	StoreInfos *AccountsStoreInfosService
}

func NewAccountsAvailsService(s *Service) *AccountsAvailsService {
	rs := &AccountsAvailsService{s: s}
	return rs
}

type AccountsAvailsService struct {
	s *Service
}

func NewAccountsOrdersService(s *Service) *AccountsOrdersService {
	rs := &AccountsOrdersService{s: s}
	return rs
}

type AccountsOrdersService struct {
	s *Service
}

func NewAccountsStoreInfosService(s *Service) *AccountsStoreInfosService {
	rs := &AccountsStoreInfosService{s: s}
	rs.Country = NewAccountsStoreInfosCountryService(s)
	return rs
}

type AccountsStoreInfosService struct {
	s *Service

	Country *AccountsStoreInfosCountryService
}

func NewAccountsStoreInfosCountryService(s *Service) *AccountsStoreInfosCountryService {
	rs := &AccountsStoreInfosCountryService{s: s}
	return rs
}

type AccountsStoreInfosCountryService struct {
	s *Service
}

// Avail: An Avail describes the Availability Window of a specific Edit
// in a given
// country, which means the period Google is allowed to sell or rent the
// Edit.
//
// Avails are exposed in EMA format Version 1.6b (available
// at
// http://www.movielabs.com/md/avails/)
//
// Studios can see the Avails for the Titles they own.
// Post-production houses cannot see any Avails.
type Avail struct {
	// AltId: Other identifier referring to the Edit, as defined by
	// partner.
	// Example: "GOOGLER_2006"
	AltId string `json:"altId,omitempty"`

	// AvailId: ID internally generated by Google to uniquely identify an
	// Avail.
	// Not part of EMA Specs.
	AvailId string `json:"availId,omitempty"`

	// CaptionExemption: Communicating an exempt category as defined by FCC
	// regulations.
	// It is not required for non-US Avails.
	// Example: "1"
	CaptionExemption string `json:"captionExemption,omitempty"`

	// CaptionIncluded: Communicating if caption file will be delivered.
	CaptionIncluded bool `json:"captionIncluded,omitempty"`

	// ContentId: Title Identifier. This should be the Title Level
	// EIDR.
	// Example: "10.5240/1489-49A2-3956-4B2D-FE16-5".
	ContentId string `json:"contentId,omitempty"`

	// DisplayName: The name of the studio that owns the Edit referred in
	// the Avail.
	// This is the equivalent of `studio_name` in other resources, but it
	// follows
	// the EMA nomenclature.
	// Example: "Google Films".
	DisplayName string `json:"displayName,omitempty"`

	// EncodeId: Manifestation Identifier. This should be the
	// Manifestation
	// Level EIDR.
	// Example: "10.2340/1489-49A2-3956-4B2D-FE16-7"
	EncodeId string `json:"encodeId,omitempty"`

	// End: End of term in YYYY-MM-DD format in the timezone of the
	// country
	// of the Avail.
	// "Open" if no end date is available.
	// Example: "2019-02-17"
	End string `json:"end,omitempty"`

	// EpisodeAltId: Other identifier referring to the episode, as defined
	// by partner.
	// Only available on TV avails.
	// Example: "rs_googlers_s1_3".
	EpisodeAltId string `json:"episodeAltId,omitempty"`

	// EpisodeNumber: The number assigned to the episode within a
	// season.
	// Only available on TV Avails.
	// Example: "3".
	EpisodeNumber string `json:"episodeNumber,omitempty"`

	// EpisodeTitleInternalAlias: OPTIONAL.TV Only. Title used by involved
	// parties to refer to this episode.
	// Only available on TV Avails.
	// Example: "Coding at Google".
	EpisodeTitleInternalAlias string `json:"episodeTitleInternalAlias,omitempty"`

	// FormatProfile: Indicates the format profile covered by the
	// transaction.
	//
	// Possible values:
	//   "FORMAT_PROFILE_UNSPECIFIED" - Value could not be determined,
	// please contact technical support if
	// it should.
	//   "SD" - Standard-definition format.
	//   "HD" - High-definition format.
	//   "UHD" - 4K UHD.
	FormatProfile string `json:"formatProfile,omitempty"`

	// LicenseType: Type of transaction.
	//
	// Possible values:
	//   "LICENSE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "EST" - Electronic Sell Through - purchase policy for unlimited
	// viewing.
	//   "VOD" - Video On Demand - rental policy for temporary viewing.
	//   "SVOD" - Subscription Video On Demand - used for subscription
	// platforms.
	// Not supported on Google Play.
	//   "POEST" - Pre-order Electronic Sell Through - pre-order purchase
	// only window.
	LicenseType string `json:"licenseType,omitempty"`

	// PphNames: Name of the post-production houses that manage the
	// Avail.
	// Not part of EMA Specs.
	PphNames []string `json:"pphNames,omitempty"`

	// PriceType: Type of pricing that should be applied to this Avail
	// based on how the partner classify them.
	// Example: "Tier", "WSP", "SRP", or "Category".
	PriceType string `json:"priceType,omitempty"`

	// PriceValue: Value to be applied to the pricing type.
	// Example: "4" or "2.99"
	PriceValue string `json:"priceValue,omitempty"`

	// ProductId: Edit Identifier. This should be the Edit Level
	// EIDR.
	// Example: "10.2340/1489-49A2-3956-4B2D-FE16-6"
	ProductId string `json:"productId,omitempty"`

	// RatingReason: Value representing the rating reason.
	// Rating reasons should be formatted as per
	// [EMA ratings spec](http://www.movielabs.com/md/ratings/)
	// and comma-separated for inclusion of multiple reasons.
	// Example: "L, S, V"
	RatingReason string `json:"ratingReason,omitempty"`

	// RatingSystem: Rating system applied to the version of title within
	// territory
	// of Avail.
	// Rating systems should be formatted as per
	// [EMA ratings spec](http://www.movielabs.com/md/ratings/)
	// Example: "MPAA"
	RatingSystem string `json:"ratingSystem,omitempty"`

	// RatingValue: Value representing the rating.
	// Ratings should be formatted as per
	// http://www.movielabs.com/md/ratings/
	// Example: "PG"
	RatingValue string `json:"ratingValue,omitempty"`

	// ReleaseDate: Release date of the Title in earliest released
	// territory.
	// Typically it is just the year, but it is free-form as per EMA
	// spec.
	// Examples: "1979", "Oct 2014"
	ReleaseDate string `json:"releaseDate,omitempty"`

	// SeasonAltId: Other identifier referring to the season, as defined by
	// partner.
	// Only available on TV avails.
	// Example: "rs_googlers_s1".
	SeasonAltId string `json:"seasonAltId,omitempty"`

	// SeasonNumber: The number assigned to the season within a series.
	// Only available on TV Avails.
	// Example: "1".
	SeasonNumber string `json:"seasonNumber,omitempty"`

	// SeasonTitleInternalAlias: Title used by involved parties to refer to
	// this season.
	// Only available on TV Avails.
	// Example: "Googlers, The".
	SeasonTitleInternalAlias string `json:"seasonTitleInternalAlias,omitempty"`

	// SeriesAltId: Other identifier referring to the series, as defined by
	// partner.
	// Only available on TV avails.
	// Example: "rs_googlers".
	SeriesAltId string `json:"seriesAltId,omitempty"`

	// SeriesTitleInternalAlias: Title used by involved parties to refer to
	// this series.
	// Only available on TV Avails.
	// Example: "Googlers, The".
	SeriesTitleInternalAlias string `json:"seriesTitleInternalAlias,omitempty"`

	// Start: Start of term in YYYY-MM-DD format in the timezone of
	// the
	// country of the Avail.
	// Example: "2013-05-14".
	Start string `json:"start,omitempty"`

	// StoreLanguage: Spoken language of the intended audience.
	// Language shall be encoded in accordance with RFC 5646.
	// Example: "fr".
	StoreLanguage string `json:"storeLanguage,omitempty"`

	// SuppressionLiftDate: First date an Edit could be publically announced
	// as becoming
	// available at a specific future date in territory of Avail.
	// *Not* the Avail start date or pre-order start date.
	// Format is YYYY-MM-DD.
	// Only available for pre-orders.
	// Example: "2012-12-10"
	SuppressionLiftDate string `json:"suppressionLiftDate,omitempty"`

	// Territory: ISO 3166-1 alpha-2 country code for the country or
	// territory
	// of this Avail.
	// For Avails, we use Territory in lieu of Country to comply with
	// EMA specifications.
	// But please note that Territory and Country identify the same
	// thing.
	// Example: "US".
	Territory string `json:"territory,omitempty"`

	// TitleInternalAlias: Title used by involved parties to refer to this
	// content.
	// Example: "Googlers, The".
	// Only available on Movie Avails.
	TitleInternalAlias string `json:"titleInternalAlias,omitempty"`

	// VideoId: Google-generated ID identifying the video linked to this
	// Avail, once
	// delivered.
	// Not part of EMA Specs.
	// Example: 'gtry456_xc'
	VideoId string `json:"videoId,omitempty"`

	// WorkType: Work type as enumerated in EMA.
	//
	// Possible values:
	//   "TITLE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "MOVIE" - A movie picture.
	//   "SEASON" - A season of a TV show.
	//   "EPISODE" - An episode of a TV show.
	//   "BUNDLE" - A collection of movies, i.e. "Googlers 1 and Googlers,
	// the return"
	WorkType string `json:"workType,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AltId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AltId") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Avail) MarshalJSON() ([]byte, error) {
	type NoMethod Avail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListAvailsResponse: Response to the 'ListAvails' method.
type ListAvailsResponse struct {
	// Avails: List of Avails that match the request criteria.
	Avails []*Avail `json:"avails,omitempty"`

	// NextPageToken: See _List methods rules_ for info about this field.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: See _List methods rules_ for more information about this
	// field.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Avails") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Avails") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListAvailsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAvailsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListOrdersResponse: Response to the 'ListOrders' method.
type ListOrdersResponse struct {
	// NextPageToken: See _List methods rules_ for info about this field.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Orders: List of Orders that match the request criteria.
	Orders []*Order `json:"orders,omitempty"`

	// TotalSize: See _List methods rules_ for more information about this
	// field.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListOrdersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListOrdersResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListStoreInfosResponse: Response to the 'ListStoreInfos' method.
type ListStoreInfosResponse struct {
	// NextPageToken: See 'List methods rules' for info about this field.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// StoreInfos: List of StoreInfos that match the request criteria.
	StoreInfos []*StoreInfo `json:"storeInfos,omitempty"`

	// TotalSize: See _List methods rules_ for more information about this
	// field.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListStoreInfosResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListStoreInfosResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Order: An Order tracks the fulfillment of an Edit when delivered
// using the
// legacy, non-component-based delivery.
//
// Each Order is uniquely identified by an `order_id`, which is
// generated
// by Google.
//
// Externally, Orders can also be identified by partners using its
// `custom_id`
// (when provided).
type Order struct {
	// ApprovedTime: Timestamp when the Order was approved.
	ApprovedTime string `json:"approvedTime,omitempty"`

	// ChannelId: YouTube Channel ID that should be used to fulfill the
	// Order.
	// Example: "UCRG64darCZhb".
	ChannelId string `json:"channelId,omitempty"`

	// ChannelName: YouTube Channel Name that should be used to fulfill the
	// Order.
	// Example: "Google_channel".
	ChannelName string `json:"channelName,omitempty"`

	// Countries: Countries where the Order is available,
	// using the "ISO 3166-1 alpha-2" format (example: "US").
	Countries []string `json:"countries,omitempty"`

	// CustomId: ID that can be used to externally identify an Order.
	// This ID is provided by partners when submitting the Avails.
	// Example: 'GOOGLER_2006'
	CustomId string `json:"customId,omitempty"`

	// EarliestAvailStartTime: Timestamp of the earliest start date of the
	// Avails
	// linked to this Order.
	EarliestAvailStartTime string `json:"earliestAvailStartTime,omitempty"`

	// EpisodeName: Default Episode name,
	// usually in the language of the country of origin.
	// Only available for TV Edits
	// Example: "Googlers, The - Pilot".
	EpisodeName string `json:"episodeName,omitempty"`

	// LegacyPriority: Legacy Order priority, as defined by Google.
	// Example: 'P0'
	LegacyPriority string `json:"legacyPriority,omitempty"`

	// Name: Default Edit name,
	// usually in the language of the country of origin.
	// Example: "Googlers, The".
	Name string `json:"name,omitempty"`

	// NormalizedPriority: A simpler representation of the priority.
	//
	// Possible values:
	//   "NORMALIZED_PRIORITY_UNSPECIFIED" - Value could not be determined,
	// please contact technical support if
	// it should.
	//   "LOW_PRIORITY" - A low-priority asset, typically from a library
	// movie.
	//   "HIGH_PRIORITY" - A high-priority asset, typically from a new
	// release or box office hit.
	NormalizedPriority string `json:"normalizedPriority,omitempty"`

	// OrderId: ID internally generated by Google to uniquely identify an
	// Order.
	// Example: 'abcde12_x'
	OrderId string `json:"orderId,omitempty"`

	// OrderedTime: Timestamp when the Order was created.
	OrderedTime string `json:"orderedTime,omitempty"`

	// PphName: Name of the post-production house that manages the Edit
	// ordered.
	PphName string `json:"pphName,omitempty"`

	// Priority: Order priority, as defined by Google.
	// The higher the value, the higher the priority.
	// Example: 90
	Priority float64 `json:"priority,omitempty"`

	// ReceivedTime: Timestamp when the Order was fulfilled.
	ReceivedTime string `json:"receivedTime,omitempty"`

	// RejectionNote: Field explaining why an Order has been
	// rejected.
	// Example: "Trailer audio is 2ch mono, please re-deliver in stereo".
	RejectionNote string `json:"rejectionNote,omitempty"`

	// SeasonName: Default Season name,
	// usually in the language of the country of origin.
	// Only available for TV Edits
	// Example: "Googlers, The - A Brave New World".
	SeasonName string `json:"seasonName,omitempty"`

	// ShowName: Default Show name,
	// usually in the language of the country of origin.
	// Only available for TV Edits
	// Example: "Googlers, The".
	ShowName string `json:"showName,omitempty"`

	// Status: High-level status of the order.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "STATUS_APPROVED" - Approved by Google.
	//   "STATUS_FAILED" - Waiting for partner to re-deliver the asset after
	// a rejection by Google.
	//   "STATUS_PROCESSING" - Waiting for Google to process the asset.
	//   "STATUS_UNFULFILLED" - Waiting for partner to deliver the asset.
	//   "STATUS_NOT_AVAILABLE" - Used when Status is not available (i.e:
	// Orders for TV Seasons).
	Status string `json:"status,omitempty"`

	// StatusDetail: Detailed status of the order
	//
	// Possible values:
	//   "ORDER_STATUS_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "ORDER_STATUS_QC_APPROVED" - Approved by Google's Quality Control
	// team.
	//   "ORDER_STATUS_QC_REJECTION" - Rejected by Google's Quality Control
	// team, pending partner redelivery.
	//   "ORDER_STATUS_INTERNAL_FIX" - Internal error while processing the
	// Order.
	//   "ORDER_STATUS_OPEN_ORDER" - Waiting for initial delivery from
	// partner.
	//   "ORDER_STATUS_NOT_AVAILABLE" - Used on Orders that do not have
	// Status, like TV Seasons.
	//   "ORDER_STATUS_AWAITING_REDELIVERY" - Waiting for re-delivery from
	// partner.
	//   "ORDER_STATUS_READY_FOR_QC" - Asset was delivered by partner, but
	// is being reviewed by Google's
	// Quality Control team.
	//   "ORDER_STATUS_FILE_PROCESSING" - Waiting for Google to process the
	// asset.
	StatusDetail string `json:"statusDetail,omitempty"`

	// StudioName: Name of the studio that owns the Edit ordered.
	StudioName string `json:"studioName,omitempty"`

	// Type: Type of the Edit linked to the Order.
	//
	// Possible values:
	//   "TITLE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "MOVIE" - A movie picture.
	//   "SEASON" - A season of a TV show.
	//   "EPISODE" - An episode of a TV show.
	//   "BUNDLE" - A collection of movies, i.e. "Googlers 1 and Googlers,
	// the return"
	Type string `json:"type,omitempty"`

	// VideoId: Google-generated ID identifying the video linked to this
	// Order, once
	// delivered.
	// Example: 'gtry456_xc'.
	VideoId string `json:"videoId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ApprovedTime") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApprovedTime") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Order) MarshalJSON() ([]byte, error) {
	type NoMethod Order
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Order) UnmarshalJSON(data []byte) error {
	type NoMethod Order
	var s1 struct {
		Priority gensupport.JSONFloat64 `json:"priority"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Priority = float64(s1.Priority)
	return nil
}

// StoreInfo: Information about a playable sequence (video) associated
// with an Edit
// and available at the Google Play Store.
//
// Internally, each StoreInfo is uniquely identified by a `video_id`
// and `country`.
//
// Externally, Title-level EIDR or Edit-level EIDR, if provided,
// can also be used to identify a specific title or edit in a country.
type StoreInfo struct {
	// AudioTracks: Audio tracks available for this Edit.
	AudioTracks []string `json:"audioTracks,omitempty"`

	// Country: Country where Edit is available in ISO 3166-1 alpha-2
	// country
	// code.
	// Example: "US".
	Country string `json:"country,omitempty"`

	// EditLevelEidr: Edit-level EIDR ID.
	// Example: "10.5240/1489-49A2-3956-4B2D-FE16-6".
	EditLevelEidr string `json:"editLevelEidr,omitempty"`

	// EpisodeNumber: The number assigned to the episode within a
	// season.
	// Only available on TV Edits.
	// Example: "1".
	EpisodeNumber string `json:"episodeNumber,omitempty"`

	// HasAudio51: Whether the Edit has a 5.1 channel audio track.
	HasAudio51 bool `json:"hasAudio51,omitempty"`

	// HasEstOffer: Whether the Edit has a EST offer.
	HasEstOffer bool `json:"hasEstOffer,omitempty"`

	// HasHdOffer: Whether the Edit has a HD offer.
	HasHdOffer bool `json:"hasHdOffer,omitempty"`

	// HasInfoCards: Whether the Edit has info cards.
	HasInfoCards bool `json:"hasInfoCards,omitempty"`

	// HasSdOffer: Whether the Edit has a SD offer.
	HasSdOffer bool `json:"hasSdOffer,omitempty"`

	// HasVodOffer: Whether the Edit has a VOD offer.
	HasVodOffer bool `json:"hasVodOffer,omitempty"`

	// LiveTime: Timestamp when the Edit went live on the Store.
	LiveTime string `json:"liveTime,omitempty"`

	// Mid: Knowledge Graph ID associated to this Edit, if available.
	// This ID links the Edit to its knowledge entity, externally
	// accessible
	// at http://freebase.com.
	// In the absense of Title EIDR or Edit EIDR, this ID helps link
	// together
	// multiple Edits across countries.
	// Example: '/m/0ffx29'
	Mid string `json:"mid,omitempty"`

	// Name: Default Edit name, usually in the language of the country
	// of
	// origin.
	// Example: "Googlers, The".
	Name string `json:"name,omitempty"`

	// PphNames: Name of the post-production houses that manage the Edit.
	PphNames []string `json:"pphNames,omitempty"`

	// SeasonId: Google-generated ID identifying the season linked to the
	// Edit.
	// Only available for TV Edits.
	// Example: 'ster23ex'
	SeasonId string `json:"seasonId,omitempty"`

	// SeasonName: Default Season name, usually in the language of the
	// country of
	// origin.
	// Only available for TV Edits
	// Example: "Googlers, The - A Brave New World".
	SeasonName string `json:"seasonName,omitempty"`

	// SeasonNumber: The number assigned to the season within a show.
	// Only available on TV Edits.
	// Example: "1".
	SeasonNumber string `json:"seasonNumber,omitempty"`

	// ShowId: Google-generated ID identifying the show linked to the
	// Edit.
	// Only available for TV Edits.
	// Example: 'et2hsue_x'
	ShowId string `json:"showId,omitempty"`

	// ShowName: Default Show name, usually in the language of the country
	// of
	// origin.
	// Only available for TV Edits
	// Example: "Googlers, The".
	ShowName string `json:"showName,omitempty"`

	// StudioName: Name of the studio that owns the Edit ordered.
	StudioName string `json:"studioName,omitempty"`

	// Subtitles: Subtitles available for this Edit.
	Subtitles []string `json:"subtitles,omitempty"`

	// TitleLevelEidr: Title-level EIDR ID.
	// Example: "10.5240/1489-49A2-3956-4B2D-FE16-5".
	TitleLevelEidr string `json:"titleLevelEidr,omitempty"`

	// TrailerId: Google-generated ID identifying the trailer linked to the
	// Edit.
	// Example: 'bhd_4e_cx'
	TrailerId string `json:"trailerId,omitempty"`

	// Type: Edit type, like Movie, Episode or Season.
	//
	// Possible values:
	//   "TITLE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "MOVIE" - A movie picture.
	//   "SEASON" - A season of a TV show.
	//   "EPISODE" - An episode of a TV show.
	//   "BUNDLE" - A collection of movies, i.e. "Googlers 1 and Googlers,
	// the return"
	Type string `json:"type,omitempty"`

	// VideoId: Google-generated ID identifying the video linked to the
	// Edit.
	// Example: 'gtry456_xc'
	VideoId string `json:"videoId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AudioTracks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AudioTracks") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *StoreInfo) MarshalJSON() ([]byte, error) {
	type NoMethod StoreInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "playmoviespartner.accounts.avails.get":

type AccountsAvailsGetCall struct {
	s            *Service
	accountId    string
	availId      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get an Avail given its avail group id and avail id.
func (r *AccountsAvailsService) Get(accountId string, availId string) *AccountsAvailsGetCall {
	c := &AccountsAvailsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	c.availId = availId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsAvailsGetCall) Fields(s ...googleapi.Field) *AccountsAvailsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsAvailsGetCall) IfNoneMatch(entityTag string) *AccountsAvailsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsAvailsGetCall) Context(ctx context.Context) *AccountsAvailsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsAvailsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsAvailsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/avails/{availId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
		"availId":   c.availId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.avails.get" call.
// Exactly one of *Avail or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Avail.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsAvailsGetCall) Do(opts ...googleapi.CallOption) (*Avail, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Avail{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get an Avail given its avail group id and avail id.",
	//   "flatPath": "v1/accounts/{accountId}/avails/{availId}",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.avails.get",
	//   "parameterOrder": [
	//     "accountId",
	//     "availId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "availId": {
	//       "description": "REQUIRED. Avail ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/avails/{availId}",
	//   "response": {
	//     "$ref": "Avail"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// method id "playmoviespartner.accounts.avails.list":

type AccountsAvailsListCall struct {
	s            *Service
	accountId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List Avails owned or managed by the partner.
//
// See _Authentication and Authorization rules_ and
// _List methods rules_ for more information about this method.
func (r *AccountsAvailsService) List(accountId string) *AccountsAvailsListCall {
	c := &AccountsAvailsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	return c
}

// AltId sets the optional parameter "altId": Filter Avails that match a
// case-insensitive, partner-specific custom id.
// NOTE: this field is deprecated and will be removed on V2;
// `alt_ids`
// should be used instead.
func (c *AccountsAvailsListCall) AltId(altId string) *AccountsAvailsListCall {
	c.urlParams_.Set("altId", altId)
	return c
}

// AltIds sets the optional parameter "altIds": Filter Avails that match
// (case-insensitive) any of the given partner-specific custom ids.
func (c *AccountsAvailsListCall) AltIds(altIds ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("altIds", append([]string{}, altIds...))
	return c
}

// PageSize sets the optional parameter "pageSize": See _List methods
// rules_ for info about this field.
func (c *AccountsAvailsListCall) PageSize(pageSize int64) *AccountsAvailsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": See _List methods
// rules_ for info about this field.
func (c *AccountsAvailsListCall) PageToken(pageToken string) *AccountsAvailsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PphNames sets the optional parameter "pphNames": See _List methods
// rules_ for info about this field.
func (c *AccountsAvailsListCall) PphNames(pphNames ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("pphNames", append([]string{}, pphNames...))
	return c
}

// StudioNames sets the optional parameter "studioNames": See _List
// methods rules_ for info about this field.
func (c *AccountsAvailsListCall) StudioNames(studioNames ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("studioNames", append([]string{}, studioNames...))
	return c
}

// Territories sets the optional parameter "territories": Filter Avails
// that match (case-insensitive) any of the given country codes,
// using the "ISO 3166-1 alpha-2" format (examples: "US", "us", "Us").
func (c *AccountsAvailsListCall) Territories(territories ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("territories", append([]string{}, territories...))
	return c
}

// Title sets the optional parameter "title": Filter that matches Avails
// with a `title_internal_alias`,
// `series_title_internal_alias`, `season_title_internal_alias`,
// or `episode_title_internal_alias` that contains the
// given
// case-insensitive title.
func (c *AccountsAvailsListCall) Title(title string) *AccountsAvailsListCall {
	c.urlParams_.Set("title", title)
	return c
}

// VideoIds sets the optional parameter "videoIds": Filter Avails that
// match any of the given `video_id`s.
func (c *AccountsAvailsListCall) VideoIds(videoIds ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("videoIds", append([]string{}, videoIds...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsAvailsListCall) Fields(s ...googleapi.Field) *AccountsAvailsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsAvailsListCall) IfNoneMatch(entityTag string) *AccountsAvailsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsAvailsListCall) Context(ctx context.Context) *AccountsAvailsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsAvailsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsAvailsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/avails")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.avails.list" call.
// Exactly one of *ListAvailsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListAvailsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsAvailsListCall) Do(opts ...googleapi.CallOption) (*ListAvailsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListAvailsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List Avails owned or managed by the partner.\n\nSee _Authentication and Authorization rules_ and\n_List methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/avails",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.avails.list",
	//   "parameterOrder": [
	//     "accountId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "altId": {
	//       "description": "Filter Avails that match a case-insensitive, partner-specific custom id.\nNOTE: this field is deprecated and will be removed on V2; `alt_ids`\nshould be used instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "altIds": {
	//       "description": "Filter Avails that match (case-insensitive) any of the given partner-specific custom ids.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pphNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "studioNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "territories": {
	//       "description": "Filter Avails that match (case-insensitive) any of the given country codes,\nusing the \"ISO 3166-1 alpha-2\" format (examples: \"US\", \"us\", \"Us\").",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "title": {
	//       "description": "Filter that matches Avails with a `title_internal_alias`,\n`series_title_internal_alias`, `season_title_internal_alias`,\nor `episode_title_internal_alias` that contains the given\ncase-insensitive title.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoIds": {
	//       "description": "Filter Avails that match any of the given `video_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/avails",
	//   "response": {
	//     "$ref": "ListAvailsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountsAvailsListCall) Pages(ctx context.Context, f func(*ListAvailsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "playmoviespartner.accounts.orders.get":

type AccountsOrdersGetCall struct {
	s            *Service
	accountId    string
	orderId      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get an Order given its id.
//
// See _Authentication and Authorization rules_ and
// _Get methods rules_ for more information about this method.
func (r *AccountsOrdersService) Get(accountId string, orderId string) *AccountsOrdersGetCall {
	c := &AccountsOrdersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	c.orderId = orderId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsOrdersGetCall) Fields(s ...googleapi.Field) *AccountsOrdersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsOrdersGetCall) IfNoneMatch(entityTag string) *AccountsOrdersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsOrdersGetCall) Context(ctx context.Context) *AccountsOrdersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsOrdersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsOrdersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/orders/{orderId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
		"orderId":   c.orderId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.orders.get" call.
// Exactly one of *Order or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Order.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsOrdersGetCall) Do(opts ...googleapi.CallOption) (*Order, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Order{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get an Order given its id.\n\nSee _Authentication and Authorization rules_ and\n_Get methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/orders/{orderId}",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.orders.get",
	//   "parameterOrder": [
	//     "accountId",
	//     "orderId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderId": {
	//       "description": "REQUIRED. Order ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/orders/{orderId}",
	//   "response": {
	//     "$ref": "Order"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// method id "playmoviespartner.accounts.orders.list":

type AccountsOrdersListCall struct {
	s            *Service
	accountId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List Orders owned or managed by the partner.
//
// See _Authentication and Authorization rules_ and
// _List methods rules_ for more information about this method.
func (r *AccountsOrdersService) List(accountId string) *AccountsOrdersListCall {
	c := &AccountsOrdersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	return c
}

// CustomId sets the optional parameter "customId": Filter Orders that
// match a case-insensitive, partner-specific custom id.
func (c *AccountsOrdersListCall) CustomId(customId string) *AccountsOrdersListCall {
	c.urlParams_.Set("customId", customId)
	return c
}

// Name sets the optional parameter "name": Filter that matches Orders
// with a `name`, `show`, `season` or `episode`
// that contains the given case-insensitive name.
func (c *AccountsOrdersListCall) Name(name string) *AccountsOrdersListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageSize sets the optional parameter "pageSize": See _List methods
// rules_ for info about this field.
func (c *AccountsOrdersListCall) PageSize(pageSize int64) *AccountsOrdersListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": See _List methods
// rules_ for info about this field.
func (c *AccountsOrdersListCall) PageToken(pageToken string) *AccountsOrdersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PphNames sets the optional parameter "pphNames": See _List methods
// rules_ for info about this field.
func (c *AccountsOrdersListCall) PphNames(pphNames ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("pphNames", append([]string{}, pphNames...))
	return c
}

// Status sets the optional parameter "status": Filter Orders that match
// one of the given status.
//
// Possible values:
//   "STATUS_UNSPECIFIED"
//   "STATUS_APPROVED"
//   "STATUS_FAILED"
//   "STATUS_PROCESSING"
//   "STATUS_UNFULFILLED"
//   "STATUS_NOT_AVAILABLE"
func (c *AccountsOrdersListCall) Status(status ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("status", append([]string{}, status...))
	return c
}

// StudioNames sets the optional parameter "studioNames": See _List
// methods rules_ for info about this field.
func (c *AccountsOrdersListCall) StudioNames(studioNames ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("studioNames", append([]string{}, studioNames...))
	return c
}

// VideoIds sets the optional parameter "videoIds": Filter Orders that
// match any of the given `video_id`s.
func (c *AccountsOrdersListCall) VideoIds(videoIds ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("videoIds", append([]string{}, videoIds...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsOrdersListCall) Fields(s ...googleapi.Field) *AccountsOrdersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsOrdersListCall) IfNoneMatch(entityTag string) *AccountsOrdersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsOrdersListCall) Context(ctx context.Context) *AccountsOrdersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsOrdersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsOrdersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/orders")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.orders.list" call.
// Exactly one of *ListOrdersResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOrdersResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsOrdersListCall) Do(opts ...googleapi.CallOption) (*ListOrdersResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListOrdersResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List Orders owned or managed by the partner.\n\nSee _Authentication and Authorization rules_ and\n_List methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/orders",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.orders.list",
	//   "parameterOrder": [
	//     "accountId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "customId": {
	//       "description": "Filter Orders that match a case-insensitive, partner-specific custom id.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Filter that matches Orders with a `name`, `show`, `season` or `episode`\nthat contains the given case-insensitive name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pphNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "status": {
	//       "description": "Filter Orders that match one of the given status.",
	//       "enum": [
	//         "STATUS_UNSPECIFIED",
	//         "STATUS_APPROVED",
	//         "STATUS_FAILED",
	//         "STATUS_PROCESSING",
	//         "STATUS_UNFULFILLED",
	//         "STATUS_NOT_AVAILABLE"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "studioNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "videoIds": {
	//       "description": "Filter Orders that match any of the given `video_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/orders",
	//   "response": {
	//     "$ref": "ListOrdersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountsOrdersListCall) Pages(ctx context.Context, f func(*ListOrdersResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "playmoviespartner.accounts.storeInfos.list":

type AccountsStoreInfosListCall struct {
	s            *Service
	accountId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List StoreInfos owned or managed by the partner.
//
// See _Authentication and Authorization rules_ and
// _List methods rules_ for more information about this method.
func (r *AccountsStoreInfosService) List(accountId string) *AccountsStoreInfosListCall {
	c := &AccountsStoreInfosListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	return c
}

// Countries sets the optional parameter "countries": Filter StoreInfos
// that match (case-insensitive) any of the given country
// codes, using the "ISO 3166-1 alpha-2" format (examples: "US", "us",
// "Us").
func (c *AccountsStoreInfosListCall) Countries(countries ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("countries", append([]string{}, countries...))
	return c
}

// Mids sets the optional parameter "mids": Filter StoreInfos that match
// any of the given `mid`s.
func (c *AccountsStoreInfosListCall) Mids(mids ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("mids", append([]string{}, mids...))
	return c
}

// Name sets the optional parameter "name": Filter that matches
// StoreInfos with a `name` or `show_name`
// that contains the given case-insensitive name.
func (c *AccountsStoreInfosListCall) Name(name string) *AccountsStoreInfosListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageSize sets the optional parameter "pageSize": See _List methods
// rules_ for info about this field.
func (c *AccountsStoreInfosListCall) PageSize(pageSize int64) *AccountsStoreInfosListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": See _List methods
// rules_ for info about this field.
func (c *AccountsStoreInfosListCall) PageToken(pageToken string) *AccountsStoreInfosListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PphNames sets the optional parameter "pphNames": See _List methods
// rules_ for info about this field.
func (c *AccountsStoreInfosListCall) PphNames(pphNames ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("pphNames", append([]string{}, pphNames...))
	return c
}

// SeasonIds sets the optional parameter "seasonIds": Filter StoreInfos
// that match any of the given `season_id`s.
func (c *AccountsStoreInfosListCall) SeasonIds(seasonIds ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("seasonIds", append([]string{}, seasonIds...))
	return c
}

// StudioNames sets the optional parameter "studioNames": See _List
// methods rules_ for info about this field.
func (c *AccountsStoreInfosListCall) StudioNames(studioNames ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("studioNames", append([]string{}, studioNames...))
	return c
}

// VideoId sets the optional parameter "videoId": Filter StoreInfos that
// match a given `video_id`.
// NOTE: this field is deprecated and will be removed on V2;
// `video_ids`
// should be used instead.
func (c *AccountsStoreInfosListCall) VideoId(videoId string) *AccountsStoreInfosListCall {
	c.urlParams_.Set("videoId", videoId)
	return c
}

// VideoIds sets the optional parameter "videoIds": Filter StoreInfos
// that match any of the given `video_id`s.
func (c *AccountsStoreInfosListCall) VideoIds(videoIds ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("videoIds", append([]string{}, videoIds...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsStoreInfosListCall) Fields(s ...googleapi.Field) *AccountsStoreInfosListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsStoreInfosListCall) IfNoneMatch(entityTag string) *AccountsStoreInfosListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsStoreInfosListCall) Context(ctx context.Context) *AccountsStoreInfosListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsStoreInfosListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsStoreInfosListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/storeInfos")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.storeInfos.list" call.
// Exactly one of *ListStoreInfosResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListStoreInfosResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsStoreInfosListCall) Do(opts ...googleapi.CallOption) (*ListStoreInfosResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListStoreInfosResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List StoreInfos owned or managed by the partner.\n\nSee _Authentication and Authorization rules_ and\n_List methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/storeInfos",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.storeInfos.list",
	//   "parameterOrder": [
	//     "accountId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "countries": {
	//       "description": "Filter StoreInfos that match (case-insensitive) any of the given country\ncodes, using the \"ISO 3166-1 alpha-2\" format (examples: \"US\", \"us\", \"Us\").",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "mids": {
	//       "description": "Filter StoreInfos that match any of the given `mid`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Filter that matches StoreInfos with a `name` or `show_name`\nthat contains the given case-insensitive name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pphNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "seasonIds": {
	//       "description": "Filter StoreInfos that match any of the given `season_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "studioNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "Filter StoreInfos that match a given `video_id`.\nNOTE: this field is deprecated and will be removed on V2; `video_ids`\nshould be used instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoIds": {
	//       "description": "Filter StoreInfos that match any of the given `video_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/storeInfos",
	//   "response": {
	//     "$ref": "ListStoreInfosResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountsStoreInfosListCall) Pages(ctx context.Context, f func(*ListStoreInfosResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "playmoviespartner.accounts.storeInfos.country.get":

type AccountsStoreInfosCountryGetCall struct {
	s            *Service
	accountId    string
	videoId      string
	country      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get a StoreInfo given its video id and country.
//
// See _Authentication and Authorization rules_ and
// _Get methods rules_ for more information about this method.
func (r *AccountsStoreInfosCountryService) Get(accountId string, videoId string, country string) *AccountsStoreInfosCountryGetCall {
	c := &AccountsStoreInfosCountryGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	c.videoId = videoId
	c.country = country
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsStoreInfosCountryGetCall) Fields(s ...googleapi.Field) *AccountsStoreInfosCountryGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsStoreInfosCountryGetCall) IfNoneMatch(entityTag string) *AccountsStoreInfosCountryGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsStoreInfosCountryGetCall) Context(ctx context.Context) *AccountsStoreInfosCountryGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsStoreInfosCountryGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsStoreInfosCountryGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/storeInfos/{videoId}/country/{country}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
		"videoId":   c.videoId,
		"country":   c.country,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.storeInfos.country.get" call.
// Exactly one of *StoreInfo or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *StoreInfo.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AccountsStoreInfosCountryGetCall) Do(opts ...googleapi.CallOption) (*StoreInfo, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &StoreInfo{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get a StoreInfo given its video id and country.\n\nSee _Authentication and Authorization rules_ and\n_Get methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/storeInfos/{videoId}/country/{country}",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.storeInfos.country.get",
	//   "parameterOrder": [
	//     "accountId",
	//     "videoId",
	//     "country"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "country": {
	//       "description": "REQUIRED. Edit country.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "REQUIRED. Video ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/storeInfos/{videoId}/country/{country}",
	//   "response": {
	//     "$ref": "StoreInfo"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}
