/*
* Copyright 2010, Maarten Billemont
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lyndir.omicron.api;
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.lyndir.lhunath.opal.system.util.*;
import java.util.Objects;
import javax.annotation.Nullable;
/**
* @author lhunath, 2013-08-04
*/
public abstract class ResourceCost extends MetaObject {
/**
* @return The amount of each type of resource required by this cost.
*/
protected abstract ImmutableMap<ResourceType, Integer> getQuantitiesByResourceType();
/**
* Create a new zero resource cost instance.
*
* @return A new immutable resource cost instance.
*/
public static ImmutableResourceCost immutable() {
return new ImmutableResourceCost();
}
/**
* Create a new resource cost initialized with the given resource costs.
*
* @param resourceCost The type of resources to initialize a cost with.
*
* @return A new immutable resource cost instance.
*/
public static ImmutableResourceCost immutable(final ResourceCost resourceCost) {
return new ImmutableResourceCost( resourceCost.getQuantitiesByResourceType() );
}
/**
* Create a new resource cost initialized by the given amount of resources of the given type.
*
* @param resourceType The type of resources to initialize a cost with.
* @param amount The amount of resources of the given type.
*
* @return A new immutable resource cost instance.
*/
public static ImmutableResourceCost immutableOf(final ResourceType resourceType, final int amount) {
return new ImmutableResourceCost( ImmutableMap.of( resourceType, amount ) );
}
/**
* Create a new zero resource cost instance.
*
* @return A new mutable resource cost instance.
*/
public static MutableResourceCost mutable() {
return new MutableResourceCost();
}
/**
* Create a new resource cost initialized with the given resource costs.
*
* @param resourceCost The type of resources to initialize a cost with.
*
* @return A new mutable resource cost instance.
*/
public static MutableResourceCost mutable(final ResourceCost resourceCost) {
return new MutableResourceCost( resourceCost.getQuantitiesByResourceType() );
}
/**
* Create a new resource cost initialized by the given amount of resources of the given type.
*
* @param resourceType The type of resources to initialize a cost with.
* @param amount The amount of resources of the given type.
*
* @return A new mutable resource cost instance.
*/
public static MutableResourceCost mutableOf(final ResourceType resourceType, final int amount) {
return new MutableResourceCost( ImmutableMap.of( resourceType, amount ) );
}
/**
* Get the resource cost for the resources of the given type.
*
* @param resourceType The type of resources to get the cost of.
*
* @return The amount of resources of the given type that are required by this resource cost.
*/
public int get(final ResourceType resourceType) {
return ifNotNullElse( getQuantitiesByResourceType().get( resourceType ), 0 );
}
/**
* Reduce the resource cost of the given type by the given amount.
*
* @param resourceType The type of resources to reduce the cost of.
* @param term The amount with which to reduce the resource cost of the given type.
*/
public abstract ResourceCost reduce(ResourceType resourceType, int term);
/**
* Add the given term to the resource cost of the given type.
*
* @param resourceType The type of resources to increase the cost of.
* @param term The amount with which to increase the resource cost of the given type.
*/
public abstract ResourceCost add(ResourceType resourceType, int term);
/**
* Add the cost of all resources given to this resource cost.
*
* @param resourceCost The resource cost to add to this resource cost.
*/
public abstract ResourceCost add(ResourceCost resourceCost);
/**
* Multiply the cost of the resources of the given type by the given factor.
*
* @param factor The factor to multiply with.
*/
public abstract ResourceCost multiply(ResourceType resourceType, int factor);
/**
* Multiply the cost of all resources by the given factor.
*
* @param factor The factor to multiply with.
*/
public abstract ResourceCost multiply(int factor);
public boolean isZero() {
return FluentIterable.from( getQuantitiesByResourceType().values() ).filter( resourceQuantity -> resourceQuantity > 0 ).isEmpty();
}
@Override
public String toString() {
return String.format( "{%s: %s}", getClass().getSimpleName(), describe( getQuantitiesByResourceType() ) );
}
@Override
public int hashCode() {
return Objects.hash( getQuantitiesByResourceType() );
}
@Override
public boolean equals(@Nullable final Object obj) {
if (obj == this)
return true;
if (!(obj instanceof ResourceCost))
return false;
return getQuantitiesByResourceType().equals( ((ResourceCost) obj).getQuantitiesByResourceType() );
}
}