// Package qpxexpress provides access to the QPX Express API.
//
// See http://developers.google.com/qpx-express
//
// Usage example:
//
//   import "google.golang.org/api/qpxexpress/v1"
//   ...
//   qpxexpressService, err := qpxexpress.New(oauthHttpClient)
package qpxexpress // import "google.golang.org/api/qpxexpress/v1"

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	context "golang.org/x/net/context"
	ctxhttp "golang.org/x/net/context/ctxhttp"
	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

// 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
var _ = ctxhttp.Do

const apiId = "qpxExpress:v1"
const apiName = "qpxExpress"
const apiVersion = "v1"
const basePath = "https://www.googleapis.com/qpxExpress/v1/trips/"

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

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

	Trips *TripsService
}

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

func NewTripsService(s *Service) *TripsService {
	rs := &TripsService{s: s}
	return rs
}

type TripsService struct {
	s *Service
}

// AircraftData: The make, model, and type of an aircraft.
type AircraftData struct {
	// Code: The aircraft code. For example, for a Boeing 777 the code would
	// be 777.
	Code string `json:"code,omitempty"`

	// Kind: Identifies this as an aircraftData object. Value: the fixed
	// string qpxexpress#aircraftData
	Kind string `json:"kind,omitempty"`

	// Name: The name of an aircraft, for example Boeing 777.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") 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:"-"`
}

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

// AirportData: An airport.
type AirportData struct {
	// City: The city code an airport is located in. For example, for JFK
	// airport, this is NYC.
	City string `json:"city,omitempty"`

	// Code: An airport's code. For example, for Boston Logan airport, this
	// is BOS.
	Code string `json:"code,omitempty"`

	// Kind: Identifies this as an airport object. Value: the fixed string
	// qpxexpress#airportData.
	Kind string `json:"kind,omitempty"`

	// Name: The name of an airport. For example, for airport BOS the name
	// is "Boston Logan International".
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "City") 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:"-"`
}

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

// BagDescriptor: Information about an item of baggage.
type BagDescriptor struct {
	// CommercialName: Provides the commercial name for an optional service.
	CommercialName string `json:"commercialName,omitempty"`

	// Count: How many of this type of bag will be checked on this flight.
	Count int64 `json:"count,omitempty"`

	// Description: A description of the baggage.
	Description []string `json:"description,omitempty"`

	// Kind: Identifies this as a baggage object. Value: the fixed string
	// qpxexpress#bagDescriptor.
	Kind string `json:"kind,omitempty"`

	// Subcode: The standard IATA subcode used to identify this optional
	// service.
	Subcode string `json:"subcode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CommercialName") 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:"-"`
}

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

// CarrierData: Information about a carrier (ie. an airline, bus line,
// railroad, etc) that might be useful to display to an end-user.
type CarrierData struct {
	// Code: The IATA designator of a carrier (airline, etc). For example,
	// for American Airlines, the code is AA.
	Code string `json:"code,omitempty"`

	// Kind: Identifies this as a kind of carrier (ie. an airline, bus line,
	// railroad, etc). Value: the fixed string qpxexpress#carrierData.
	Kind string `json:"kind,omitempty"`

	// Name: The long, full name of a carrier. For example: American
	// Airlines.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") 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:"-"`
}

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

// CityData: Information about a city that might be useful to an
// end-user; typically the city of an airport.
type CityData struct {
	// Code: The IATA character ID of a city. For example, for Boston this
	// is BOS.
	Code string `json:"code,omitempty"`

	// Country: The two-character country code of the country the city is
	// located in. For example, US for the United States of America.
	Country string `json:"country,omitempty"`

	// Kind: Identifies this as a city, typically with one or more airports.
	// Value: the fixed string qpxexpress#cityData.
	Kind string `json:"kind,omitempty"`

	// Name: The full name of a city. An example would be: New York.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") 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:"-"`
}

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

// Data: Detailed information about components found in the solutions of
// this response, including a trip's airport, city, taxes, airline, and
// aircraft.
type Data struct {
	// Aircraft: The aircraft that is flying between an origin and
	// destination.
	Aircraft []*AircraftData `json:"aircraft,omitempty"`

	// Airport: The airport of an origin or destination.
	Airport []*AirportData `json:"airport,omitempty"`

	// Carrier: The airline carrier of the aircraft flying between an origin
	// and destination. Allowed values are IATA carrier codes.
	Carrier []*CarrierData `json:"carrier,omitempty"`

	// City: The city that is either the origin or destination of part of a
	// trip.
	City []*CityData `json:"city,omitempty"`

	// Kind: Identifies this as QPX Express response resource, including a
	// trip's airport, city, taxes, airline, and aircraft. Value: the fixed
	// string qpxexpress#data.
	Kind string `json:"kind,omitempty"`

	// Tax: The taxes due for flying between an origin and a destination.
	Tax []*TaxData `json:"tax,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Aircraft") 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:"-"`
}

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

// FareInfo: Complete information about a fare used in the solution to a
// low-fare search query. In the airline industry a fare is a price an
// airline charges for one-way travel between two points. A fare
// typically contains a carrier code, two city codes, a price, and a
// fare basis. (A fare basis is a one-to-eight character alphanumeric
// code used to identify a fare.)
type FareInfo struct {
	BasisCode string `json:"basisCode,omitempty"`

	// Carrier: The carrier of the aircraft or other vehicle commuting
	// between two points.
	Carrier string `json:"carrier,omitempty"`

	// Destination: The city code of the city the trip ends at.
	Destination string `json:"destination,omitempty"`

	// Id: A unique identifier of the fare.
	Id string `json:"id,omitempty"`

	// Kind: Identifies this as a fare object. Value: the fixed string
	// qpxexpress#fareInfo.
	Kind string `json:"kind,omitempty"`

	// Origin: The city code of the city the trip begins at.
	Origin string `json:"origin,omitempty"`

	// Private: Whether this is a private fare, for example one offered only
	// to select customers rather than the general public.
	Private bool `json:"private,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BasisCode") 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:"-"`
}

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

// FlightInfo: A flight is a sequence of legs with the same airline
// carrier and flight number. (A leg is the smallest unit of travel, in
// the case of a flight a takeoff immediately followed by a landing at
// two set points on a particular carrier with a particular flight
// number.) The naive view is that a flight is scheduled travel of an
// aircraft between two points, with possibly intermediate stops, but
// carriers will frequently list flights that require a change of
// aircraft between legs.
type FlightInfo struct {
	Carrier string `json:"carrier,omitempty"`

	// Number: The flight number.
	Number string `json:"number,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Carrier") 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:"-"`
}

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

// FreeBaggageAllowance: Information about free baggage allowed on one
// segment of a trip.
type FreeBaggageAllowance struct {
	// BagDescriptor: A representation of a type of bag, such as an ATPCo
	// subcode, Commercial Name, or other description.
	BagDescriptor []*BagDescriptor `json:"bagDescriptor,omitempty"`

	// Kilos: The maximum number of kilos all the free baggage together may
	// weigh.
	Kilos int64 `json:"kilos,omitempty"`

	// KilosPerPiece: The maximum number of kilos any one piece of baggage
	// may weigh.
	KilosPerPiece int64 `json:"kilosPerPiece,omitempty"`

	// Kind: Identifies this as free baggage object, allowed on one segment
	// of a trip. Value: the fixed string qpxexpress#freeBaggageAllowance.
	Kind string `json:"kind,omitempty"`

	// Pieces: The number of free pieces of baggage allowed.
	Pieces int64 `json:"pieces,omitempty"`

	// Pounds: The number of pounds of free baggage allowed.
	Pounds int64 `json:"pounds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BagDescriptor") 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:"-"`
}

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

// LegInfo: Information about a leg. (A leg is the smallest unit of
// travel, in the case of a flight a takeoff immediately followed by a
// landing at two set points on a particular carrier with a particular
// flight number.)
type LegInfo struct {
	// Aircraft: The aircraft (or bus, ferry, railcar, etc) travelling
	// between the two points of this leg.
	Aircraft string `json:"aircraft,omitempty"`

	// ArrivalTime: The scheduled time of arrival at the destination of the
	// leg, local to the point of arrival.
	ArrivalTime string `json:"arrivalTime,omitempty"`

	// ChangePlane: Whether you have to change planes following this leg.
	// Only applies to the next leg.
	ChangePlane bool `json:"changePlane,omitempty"`

	// ConnectionDuration: Duration of a connection following this leg, in
	// minutes.
	ConnectionDuration int64 `json:"connectionDuration,omitempty"`

	// DepartureTime: The scheduled departure time of the leg, local to the
	// point of departure.
	DepartureTime string `json:"departureTime,omitempty"`

	// Destination: The leg destination as a city and airport.
	Destination string `json:"destination,omitempty"`

	// DestinationTerminal: The terminal the flight is scheduled to arrive
	// at.
	DestinationTerminal string `json:"destinationTerminal,omitempty"`

	// Duration: The scheduled travelling time from the origin to the
	// destination.
	Duration int64 `json:"duration,omitempty"`

	// Id: An identifier that uniquely identifies this leg in the solution.
	Id string `json:"id,omitempty"`

	// Kind: Identifies this as a leg object. A leg is the smallest unit of
	// travel, in the case of a flight a takeoff immediately followed by a
	// landing at two set points on a particular carrier with a particular
	// flight number. Value: the fixed string qpxexpress#legInfo.
	Kind string `json:"kind,omitempty"`

	// Meal: A simple, general description of the meal(s) served on the
	// flight, for example: "Hot meal".
	Meal string `json:"meal,omitempty"`

	// Mileage: The number of miles in this leg.
	Mileage int64 `json:"mileage,omitempty"`

	// OnTimePerformance: In percent, the published on time performance on
	// this leg.
	OnTimePerformance int64 `json:"onTimePerformance,omitempty"`

	// OperatingDisclosure: Department of Transportation disclosure
	// information on the actual operator of a flight in a code share. (A
	// code share refers to a marketing agreement between two carriers,
	// where one carrier will list in its schedules (and take bookings for)
	// flights that are actually operated by another carrier.)
	OperatingDisclosure string `json:"operatingDisclosure,omitempty"`

	// Origin: The leg origin as a city and airport.
	Origin string `json:"origin,omitempty"`

	// OriginTerminal: The terminal the flight is scheduled to depart from.
	OriginTerminal string `json:"originTerminal,omitempty"`

	// Secure: Whether passenger information must be furnished to the United
	// States Transportation Security Administration (TSA) prior to
	// departure.
	Secure bool `json:"secure,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Aircraft") 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:"-"`
}

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

// PassengerCounts: The number and type of passengers. Unfortunately the
// definition of an infant, child, adult, and senior citizen varies
// across carriers and reservation systems.
type PassengerCounts struct {
	// AdultCount: The number of passengers that are adults.
	AdultCount int64 `json:"adultCount,omitempty"`

	// ChildCount: The number of passengers that are children.
	ChildCount int64 `json:"childCount,omitempty"`

	// InfantInLapCount: The number of passengers that are infants
	// travelling in the lap of an adult.
	InfantInLapCount int64 `json:"infantInLapCount,omitempty"`

	// InfantInSeatCount: The number of passengers that are infants each
	// assigned a seat.
	InfantInSeatCount int64 `json:"infantInSeatCount,omitempty"`

	// Kind: Identifies this as a passenger count object, representing the
	// number of passengers. Value: the fixed string
	// qpxexpress#passengerCounts.
	Kind string `json:"kind,omitempty"`

	// SeniorCount: The number of passengers that are senior citizens.
	SeniorCount int64 `json:"seniorCount,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdultCount") 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:"-"`
}

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

// PricingInfo: The price of one or more travel segments. The currency
// used to purchase tickets is usually determined by the sale/ticketing
// city or the sale/ticketing country, unless none are specified, in
// which case it defaults to that of the journey origin country.
type PricingInfo struct {
	// BaseFareTotal: The total fare in the base fare currency (the currency
	// of the country of origin). This element is only present when the
	// sales currency and the currency of the country of commencement are
	// different.
	BaseFareTotal string `json:"baseFareTotal,omitempty"`

	// Fare: The fare used to price one or more segments.
	Fare []*FareInfo `json:"fare,omitempty"`

	// FareCalculation: The horizontal fare calculation. This is a field on
	// a ticket that displays all of the relevant items that go into the
	// calculation of the fare.
	FareCalculation string `json:"fareCalculation,omitempty"`

	// Kind: Identifies this as a pricing object, representing the price of
	// one or more travel segments. Value: the fixed string
	// qpxexpress#pricingInfo.
	Kind string `json:"kind,omitempty"`

	// LatestTicketingTime: The latest ticketing time for this pricing
	// assuming the reservation occurs at ticketing time and there is no
	// change in fares/rules. The time is local to the point of sale (POS).
	LatestTicketingTime string `json:"latestTicketingTime,omitempty"`

	// Passengers: The number of passengers to which this price applies.
	Passengers *PassengerCounts `json:"passengers,omitempty"`

	// Ptc: The passenger type code for this pricing. An alphanumeric code
	// used by a carrier to restrict fares to certain categories of
	// passenger. For instance, a fare might be valid only for senior
	// citizens.
	Ptc string `json:"ptc,omitempty"`

	// Refundable: Whether the fares on this pricing are refundable.
	Refundable bool `json:"refundable,omitempty"`

	// SaleFareTotal: The total fare in the sale or equivalent currency.
	SaleFareTotal string `json:"saleFareTotal,omitempty"`

	// SaleTaxTotal: The taxes in the sale or equivalent currency.
	SaleTaxTotal string `json:"saleTaxTotal,omitempty"`

	// SaleTotal: Total per-passenger price (fare and tax) in the sale or
	// equivalent currency.
	SaleTotal string `json:"saleTotal,omitempty"`

	// SegmentPricing: The per-segment price and baggage information.
	SegmentPricing []*SegmentPricing `json:"segmentPricing,omitempty"`

	// Tax: The taxes used to calculate the tax total per ticket.
	Tax []*TaxInfo `json:"tax,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BaseFareTotal") 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:"-"`
}

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

// SegmentInfo: Details of a segment of a flight; a segment is one or
// more consecutive legs on the same flight. For example a hypothetical
// flight ZZ001, from DFW to OGG, would have one segment with two legs:
// DFW to HNL (leg 1), HNL to OGG (leg 2), and DFW to OGG (legs 1 and
// 2).
type SegmentInfo struct {
	// BookingCode: The booking code or class for this segment.
	BookingCode string `json:"bookingCode,omitempty"`

	// BookingCodeCount: The number of seats available in this booking code
	// on this segment.
	BookingCodeCount int64 `json:"bookingCodeCount,omitempty"`

	// Cabin: The cabin booked for this segment.
	Cabin string `json:"cabin,omitempty"`

	// ConnectionDuration: In minutes, the duration of the connection
	// following this segment.
	ConnectionDuration int64 `json:"connectionDuration,omitempty"`

	// Duration: The duration of the flight segment in minutes.
	Duration int64 `json:"duration,omitempty"`

	// Flight: The flight this is a segment of.
	Flight *FlightInfo `json:"flight,omitempty"`

	// Id: An id uniquely identifying the segment in the solution.
	Id string `json:"id,omitempty"`

	// Kind: Identifies this as a segment object. A segment is one or more
	// consecutive legs on the same flight. For example a hypothetical
	// flight ZZ001, from DFW to OGG, could have one segment with two legs:
	// DFW to HNL (leg 1), HNL to OGG (leg 2). Value: the fixed string
	// qpxexpress#segmentInfo.
	Kind string `json:"kind,omitempty"`

	// Leg: The legs composing this segment.
	Leg []*LegInfo `json:"leg,omitempty"`

	// MarriedSegmentGroup: The solution-based index of a segment in a
	// married segment group. Married segments can only be booked together.
	// For example, an airline might report a certain booking code as sold
	// out from Boston to Pittsburgh, but as available as part of two
	// married segments Boston to Chicago connecting through Pittsburgh. For
	// example content of this field, consider the round-trip flight ZZ1
	// PHX-PHL ZZ2 PHL-CLT ZZ3 CLT-PHX. This has three segments, with the
	// two outbound ones (ZZ1 ZZ2) married. In this case, the two outbound
	// segments belong to married segment group 0, and the return segment
	// belongs to married segment group 1.
	MarriedSegmentGroup string `json:"marriedSegmentGroup,omitempty"`

	// SubjectToGovernmentApproval: Whether the operation of this segment
	// remains subject to government approval.
	SubjectToGovernmentApproval bool `json:"subjectToGovernmentApproval,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BookingCode") 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:"-"`
}

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

// SegmentPricing: The price of this segment.
type SegmentPricing struct {
	// FareId: A segment identifier unique within a single solution. It is
	// used to refer to different parts of the same solution.
	FareId string `json:"fareId,omitempty"`

	// FreeBaggageOption: Details of the free baggage allowance on this
	// segment.
	FreeBaggageOption []*FreeBaggageAllowance `json:"freeBaggageOption,omitempty"`

	// Kind: Identifies this as a segment pricing object, representing the
	// price of this segment. Value: the fixed string
	// qpxexpress#segmentPricing.
	Kind string `json:"kind,omitempty"`

	// SegmentId: Unique identifier in the response of this segment.
	SegmentId string `json:"segmentId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FareId") 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:"-"`
}

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

// SliceInfo: Information about a slice. A slice represents a
// traveller's intent, the portion of a low-fare search corresponding to
// a traveler's request to get between two points. One-way journeys are
// generally expressed using 1 slice, round-trips using 2. For example,
// if a traveler specifies the following trip in a user interface:
// | Origin | Destination | Departure Date | | BOS | LAX | March 10,
// 2007 | | LAX | SYD | March 17, 2007 | | SYD | BOS | March 22, 2007
// |
// then this is a three slice trip.
type SliceInfo struct {
	// Duration: The duration of the slice in minutes.
	Duration int64 `json:"duration,omitempty"`

	// Kind: Identifies this as a slice object. A slice represents a
	// traveller's intent, the portion of a low-fare search corresponding to
	// a traveler's request to get between two points. One-way journeys are
	// generally expressed using 1 slice, round-trips using 2. Value: the
	// fixed string qpxexpress#sliceInfo.
	Kind string `json:"kind,omitempty"`

	// Segment: The segment(s) constituting the slice.
	Segment []*SegmentInfo `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Duration") 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:"-"`
}

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

// SliceInput: Criteria a desired slice must satisfy.
type SliceInput struct {
	// Alliance: Slices with only the carriers in this alliance should be
	// returned; do not use this field with permittedCarrier. Allowed values
	// are ONEWORLD, SKYTEAM, and STAR.
	Alliance string `json:"alliance,omitempty"`

	// Date: Departure date in YYYY-MM-DD format.
	Date string `json:"date,omitempty"`

	// Destination: Airport or city IATA designator of the destination.
	Destination string `json:"destination,omitempty"`

	// Kind: Identifies this as a slice input object, representing the
	// criteria a desired slice must satisfy. Value: the fixed string
	// qpxexpress#sliceInput.
	Kind string `json:"kind,omitempty"`

	// MaxConnectionDuration: The longest connection between two legs, in
	// minutes, you are willing to accept.
	MaxConnectionDuration int64 `json:"maxConnectionDuration,omitempty"`

	// MaxStops: The maximum number of stops you are willing to accept in
	// this slice.
	MaxStops int64 `json:"maxStops,omitempty"`

	// Origin: Airport or city IATA designator of the origin.
	Origin string `json:"origin,omitempty"`

	// PermittedCarrier: A list of 2-letter IATA airline designators. Slices
	// with only these carriers should be returned.
	PermittedCarrier []string `json:"permittedCarrier,omitempty"`

	// PermittedDepartureTime: Slices must depart in this time of day range,
	// local to the point of departure.
	PermittedDepartureTime *TimeOfDayRange `json:"permittedDepartureTime,omitempty"`

	// PreferredCabin: Prefer solutions that book in this cabin for this
	// slice. Allowed values are COACH, PREMIUM_COACH, BUSINESS, and FIRST.
	PreferredCabin string `json:"preferredCabin,omitempty"`

	// ProhibitedCarrier: A list of 2-letter IATA airline designators.
	// Exclude slices that use these carriers.
	ProhibitedCarrier []string `json:"prohibitedCarrier,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alliance") 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:"-"`
}

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

// TaxData: Tax data.
type TaxData struct {
	// Id: An identifier uniquely identifying a tax in a response.
	Id string `json:"id,omitempty"`

	// Kind: Identifies this as a tax data object, representing some tax.
	// Value: the fixed string qpxexpress#taxData.
	Kind string `json:"kind,omitempty"`

	// Name: The name of a tax.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") 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:"-"`
}

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

// TaxInfo: Tax information.
type TaxInfo struct {
	// ChargeType: Whether this is a government charge or a carrier
	// surcharge.
	ChargeType string `json:"chargeType,omitempty"`

	// Code: The code to enter in the ticket's tax box.
	Code string `json:"code,omitempty"`

	// Country: For government charges, the country levying the charge.
	Country string `json:"country,omitempty"`

	// Id: Identifier uniquely identifying this tax in a response. Not
	// present for unnamed carrier surcharges.
	Id string `json:"id,omitempty"`

	// Kind: Identifies this as a tax information object. Value: the fixed
	// string qpxexpress#taxInfo.
	Kind string `json:"kind,omitempty"`

	// SalePrice: The price of the tax in the sales or equivalent currency.
	SalePrice string `json:"salePrice,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChargeType") 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:"-"`
}

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

// TimeOfDayRange: Two times in a single day defining a time range.
type TimeOfDayRange struct {
	// EarliestTime: The earliest time of day in HH:MM format.
	EarliestTime string `json:"earliestTime,omitempty"`

	// Kind: Identifies this as a time of day range object, representing two
	// times in a single day defining a time range. Value: the fixed string
	// qpxexpress#timeOfDayRange.
	Kind string `json:"kind,omitempty"`

	// LatestTime: The latest time of day in HH:MM format.
	LatestTime string `json:"latestTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EarliestTime") 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:"-"`
}

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

// TripOption: Trip information.
type TripOption struct {
	// Id: Identifier uniquely identifying this trip in a response.
	Id string `json:"id,omitempty"`

	// Kind: Identifies this as a trip information object. Value: the fixed
	// string qpxexpress#tripOption.
	Kind string `json:"kind,omitempty"`

	// Pricing: Per passenger pricing information.
	Pricing []*PricingInfo `json:"pricing,omitempty"`

	// SaleTotal: The total price for all passengers on the trip, in the
	// form of a currency followed by an amount, e.g. USD253.35.
	SaleTotal string `json:"saleTotal,omitempty"`

	// Slice: The slices that make up this trip's itinerary.
	Slice []*SliceInfo `json:"slice,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") 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:"-"`
}

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

// TripOptionsRequest: A QPX Express search request, which will yield
// one or more solutions.
type TripOptionsRequest struct {
	// MaxPrice: Do not return solutions that cost more than this price. The
	// alphabetical part of the price is in ISO 4217. The format, in regex,
	// is [A-Z]{3}\d+(\.\d+)? Example: $102.07
	MaxPrice string `json:"maxPrice,omitempty"`

	// Passengers: Counts for each passenger type in the request.
	Passengers *PassengerCounts `json:"passengers,omitempty"`

	// Refundable: Return only solutions with refundable fares.
	Refundable bool `json:"refundable,omitempty"`

	// SaleCountry: IATA country code representing the point of sale. This
	// determines the "equivalent amount paid" currency for the ticket.
	SaleCountry string `json:"saleCountry,omitempty"`

	// Slice: The slices that make up the itinerary of this trip. A slice
	// represents a traveler's intent, the portion of a low-fare search
	// corresponding to a traveler's request to get between two points.
	// One-way journeys are generally expressed using one slice, round-trips
	// using two. An example of a one slice trip with three segments might
	// be BOS-SYD, SYD-LAX, LAX-BOS if the traveler only stopped in SYD and
	// LAX just long enough to change planes.
	Slice []*SliceInput `json:"slice,omitempty"`

	// Solutions: The number of solutions to return, maximum 500.
	Solutions int64 `json:"solutions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MaxPrice") 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:"-"`
}

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

// TripOptionsResponse: A QPX Express search response.
type TripOptionsResponse struct {
	// Data: Informational data global to list of solutions.
	Data *Data `json:"data,omitempty"`

	// Kind: Identifies this as a QPX Express trip response object, which
	// consists of zero or more solutions. Value: the fixed string
	// qpxexpress#tripOptions.
	Kind string `json:"kind,omitempty"`

	// RequestId: An identifier uniquely identifying this response.
	RequestId string `json:"requestId,omitempty"`

	// TripOption: A list of priced itinerary solutions to the QPX Express
	// query.
	TripOption []*TripOption `json:"tripOption,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Data") 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:"-"`
}

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

// TripsSearchRequest: A QPX Express search request.
type TripsSearchRequest struct {
	// Request: A QPX Express search request. Required values are at least
	// one adult or senior passenger, an origin, a destination, and a date.
	Request *TripOptionsRequest `json:"request,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Request") 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:"-"`
}

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

// TripsSearchResponse: A QPX Express search response.
type TripsSearchResponse struct {
	// Kind: Identifies this as a QPX Express API search response resource.
	// Value: the fixed string qpxExpress#tripsSearch.
	Kind string `json:"kind,omitempty"`

	// Trips: All possible solutions to the QPX Express search request.
	Trips *TripOptionsResponse `json:"trips,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Kind") 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:"-"`
}

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

// method id "qpxExpress.trips.search":

type TripsSearchCall struct {
	s                  *Service
	tripssearchrequest *TripsSearchRequest
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Search: Returns a list of flights.
func (r *TripsService) Search(tripssearchrequest *TripsSearchRequest) *TripsSearchCall {
	c := &TripsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.tripssearchrequest = tripssearchrequest
	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 *TripsSearchCall) Fields(s ...googleapi.Field) *TripsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *TripsSearchCall) Context(ctx context.Context) *TripsSearchCall {
	c.ctx_ = ctx
	return c
}

func (c *TripsSearchCall) doRequest(alt string) (*http.Response, error) {
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.tripssearchrequest)
	if err != nil {
		return nil, err
	}
	ctype := "application/json"
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "search")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	googleapi.SetOpaque(req.URL)
	req.Header.Set("Content-Type", ctype)
	req.Header.Set("User-Agent", c.s.userAgent())
	if c.ctx_ != nil {
		return ctxhttp.Do(c.ctx_, c.s.client, req)
	}
	return c.s.client.Do(req)
}

// Do executes the "qpxExpress.trips.search" call.
// Exactly one of *TripsSearchResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TripsSearchResponse.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 *TripsSearchCall) Do(opts ...googleapi.CallOption) (*TripsSearchResponse, 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 := &TripsSearchResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	if err := json.NewDecoder(res.Body).Decode(&ret); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns a list of flights.",
	//   "httpMethod": "POST",
	//   "id": "qpxExpress.trips.search",
	//   "path": "search",
	//   "request": {
	//     "$ref": "TripsSearchRequest"
	//   },
	//   "response": {
	//     "$ref": "TripsSearchResponse"
	//   }
	// }

}
