#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#    This file is part of arena.
#   
#    arena 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; either version 3 of the License or, at your
#    option, any later version.
#
#    arena is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABLITY
#    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 arena.  If not, see <http://www.gnu.org/licenses/>.

## @file
#  This file defines a class that implements a simple counter.

from Library.Memory.StringTrees import AStringLeaf
from Library.Base.Exceptions import AnException

## The format used when constructing a string representation of ACounter
cStringRepresentation = "\t{name}: {value}\n"

## The error message used when the counter reaches its limit
cErrorLimitReached = "{} count has reached its limit ({})"

## A counter.
class ACounter(AStringLeaf):
    ## Constructor
    def __init__(Self, thisName):
        AStringLeaf.__init__(Self, thisName)
    
    ## Initializer    
    def init(Self):
        result = AStringLeaf.init(Self)
        
        if result == True:
            # Establish public attributes
            ## The counter value
            Self.count = 0
            ## The counter limit
            Self.limit = 0
            
        return result
        
    ## Increment the counter by the specified amount. 
    #    
    #  If the counter limit is greater than zero (0) and the new counter value 
    #  exceeds that limit, then an exception is raised.
    def increment(Self, amount=1):
        Self.count += amount
        if (Self.limit > 0) and (Self.count >= Self.limit):
            raise AnException(cErrorLimitReached, Self.name, Self.count)
        
    ## Decrement the counter by the specified amount.
    #
    #  This routine will not allow the counter value to be negative.
    def decrement(Self, amount=1):
        Self.count -= amount
        if Self.count < 0:
            Self.count = 0
            
    ## Zero the counter value.
    def zero(Self):
        Self.count = 0
                
    # IsPrintable implementation -----------------------------------------------
    ## Return a string representation of the counter.
    #    
    #  The representation is formatted according to the specification provided
    #  in #cStringRepresentation.
    def toString(Self):
        return cStringRepresentation.format(name=Self.name, count=Self.count)
