<?php
/**
 * Money class
 * @author Jérôme Brilland
 * @version 1.0
 * @package Bluebird
 * @copyright (c) 2016-2019, Jérôme Brilland
 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License
 * @since Version 1.6
 */
final class Money {
    
    private $amount;
    
    private $currency;
    
    /**
     * Class constructor
     */
    public function __construct( $amount, $currency ) {
        if ( !Validator::validateInteger( $amount ) ) {
            throw new InvalidArgumentException();
        }
        $this->amount = $amount;
        $this->currency = $currency;
    }
    
    function getAmount() {
        return $this->amount;
    }
    
    function getCurrency() {
        return $this->currency;
    }
    
    public function equals( Money $other ) {
        return ( $this->currency == $other->getCurrency() ) && ( $this->amount == $other->amount );
    }
    
    public function greaterThan( Money $other ) {
        $this->ensureSameCurrencyWith( $other );
        return ( $this->amount > $other->amount );
    }
    
    public function greaterThanOrEquals( Money $other ) {
        $this->ensureSameCurrencyWith( $other );
        return ( $this->amount >= $other->amount );
    }
    
    public function lessThan( Money $other ) {
        $this->ensureSameCurrencyWith( $other );
        return ( $this->amount < $other->amount );
    }
    
    public function lessThanOrEquals( Money $other ) {
        $this->ensureSameCurrencyWith( $other );
        return ( $this->amount <= $other->amount );
    }
    
    public function add( Money $other ) {
        $this->ensureSameCurrencyWith( $other );
        return new Self( $this->amount + $other->amount, $this->currency );
    }
    
    public function subtract( Money $other ) {
        $this->ensureSameCurrencyWith( $other );
        return new Self( $this->amount - $other->amount, $this->currency );
    }
    
    public function multiply( $multiplier, $roundingMethod = PHP_ROUND_HALF_UP ) {
        if ( !Validator::validateNumber( $multiplier ) ) {
            throw new InvalidArgumentException();
        }
        return new Self( round( $this->amount * $multiplier, 0, $roundingMethod ), $this->currency );
    }
    
    private function ensureSameCurrencyWith( Money $other ) {
        if ( $this->currency != $other->getCurrency() ) {
            throw new InvalidArgumentException();
        }
    }
    
}
