/* $Id$ */

/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file infrastructure_func.h Functions for infrastructure sharing */

#ifndef INFRASTRUCTURE_FUNC_H
#define INFRASTRUCTURE_FUNC_H

#include "vehicle_base.h"
#include "functions.h"
#include "company_func.h"

void PayStationSharingFee(Vehicle *v, const Station *st);
void PayDailyTrackSharingFee(Train *v);
bool CheckSharingChangePossible(VehicleType type);
void HandleSharingCompanyDeletion(Owner owner);
void UpdateAllBlockSignals(Owner owner = INVALID_OWNER);

/**
 * Get the value of the sharing setting for a vehicle type.
 * @param type The type of vehicle.
 * @return     True if sharing is enabled for the given vehicle type.
 */
static FORCEINLINE bool GetSharingSetting(VehicleType type)
{
	switch (type) {
		case VEH_TRAIN:    return _settings_game.sharing.sharing_rail;
		case VEH_ROAD:     return _settings_game.sharing.sharing_road;
		case VEH_SHIP:     return _settings_game.sharing.sharing_water;
		case VEH_AIRCRAFT: return _settings_game.sharing.sharing_air;
		default: NOT_REACHED();
	}
}

/**
 * Check whether a vehicle of a given owner and type can use the infrastrucutre of a given company.
 * @param infra_owner The owner of the infrastructure.
 * @param veh_owner   Owner of the vehicle in question.
 * @param type        Type of vehicle we are talking about.
 * @return            True if infrastructure usage is allowed, false otherwise.
 */
static FORCEINLINE bool IsInfraUsageAllowed(Owner infra_owner, Owner veh_owner, VehicleType type)
{
	return infra_owner == veh_owner || infra_owner == OWNER_NONE || GetSharingSetting(type);
}

/**
 * Check whether a vehicle of a given owner and type can use the infrastrucutre on a given tile.
 * @param infra_owner The tile that may or may not be used.
 * @param veh_owner   Owner of the vehicle in question.
 * @param type        Type of vehicle we are talking about.
 * @return            True if infrastructure usage is allowed, false otherwise.
 */
static FORCEINLINE bool IsInfraTileUsageAllowed(TileIndex tile, Owner veh_owner, VehicleType type)
{
	return IsInfraUsageAllowed(GetTileOwner(tile), veh_owner, type);
}

/**
 * Is a vehicle owned by _current_company allowed to use the infrastructure of infra_owner?
 * @see IsInfraUsageAllowed
 * @note This function is to be called from DoCommands.
 * @param infra_owner Owner of the infrastructure.
 * @param type        Type of vehicle.
 * @return            True if infrastructure usage is allowed, false otherwise.
 */
static FORCEINLINE bool CheckInfraUsageAllowed(Owner infra_owner, VehicleType type)
{
	return infra_owner == OWNER_NONE || GetSharingSetting(type) || CheckOwnership(infra_owner);
}

/**
 * Check whether a given company can control this vehicle.
 * Controlling a vehicle means permission to start, stop or reverse it or to make it ignore signals.
 * @param v The vehicle which may or may not be controlled.
 * @param o The company which may or may not control this vehicle.
 * @return  True if the given company is allowed to control this vehicle.
 */
static FORCEINLINE bool IsVehicleControlAllowed(const Vehicle *v, Owner o)
{
	return v->owner == o || (v->type == VEH_TRAIN && IsTileOwner(v->tile, o));
}

/**
 * Check whether _current_company can control this vehicle.
 * @note This function is to be called from DoCommands.
 * @see IsVehicleControlAllowed
 * @param v The vehicle which may or may not be controlled.
 * @return  True if _current_company is allowed to control this vehicle.
 */
static FORCEINLINE bool CheckVehicleControlAllowed(const Vehicle *v)
{
	return (v->type == VEH_TRAIN && IsTileOwner(v->tile, _current_company)) || CheckOwnership(v->owner);
}

/**
 * Do signal states propagate from the tracks of one owner to the other?
 * @note This function should be consistent, so if it returns true for (a, b) and (b, c),
 * it should also return true for (a, c).
 * @param o1 First track owner.
 * @param o2 Second track owner.
 * @return   True if tracks of the two owners are part of the same signal block.
 */
static FORCEINLINE bool IsOneSignalBlock(Owner o1, Owner o2)
{
	return o1 == o2 || _settings_game.sharing.sharing_rail;
}

#endif /* INFRASTRUCTURE_FUNC_H */
