#file: group.py
#Copyright (C) 2005,2006,2007,2008 Evil Mr Henry, Phil Bordelon, Brian Reid,
#                        and FunnyMan3595
#This file is part of Endgame: Singularity.

#Endgame: Singularity 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 2 of the License, or
#(at your option) any later version.

#Endgame: Singularity 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 Endgame: Singularity; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#This file contains the group class, a group of person which can suspect the singularity.

from __future__ import absolute_import

from singularity.code import g
from singularity.code.spec import GenericSpec, SpecDataField


class GroupSpec(GenericSpec):

    spec_data_fields = [
        SpecDataField('suspicion_decay', converter=int, default_value=100)
    ]

    def __init__(self, id, suspicion_decay):
        super(GroupSpec, self).__init__(id)
        self.suspicion_decay = suspicion_decay
        self.discover_suspicion = 1000
        
        # String data
        self.name = ""
        self.discover_log = ""
        self.discover_desc = ""


class Group(object):

    def __init__(self, spec, diff):
        self.spec = spec
        self.suspicion = 0
        self.changed_suspicion_decay = 0
        self.base_discover_bonus = diff.discover_multiplier
        self.changed_discover_bonus = 0
        self.base_discover_suspicion = diff.suspicion_multiplier
        self.changed_discover_suspicion = 0
        self.is_actively_discovering_bases = True

    def serialize_obj(self):
        return {
            'id': g.to_internal_id('group', self.spec.id),
            'suspicion': self.suspicion,
            'is_actively_discovering_bases': self.is_actively_discovering_bases,
        }

    @classmethod
    def deserialize_obj(cls, diff, obj_data, game_version):
        spec_id = g.convert_internal_id('group', obj_data['id'])
        spec = g.groups[spec_id]
        group = Group(spec, diff)
        
        group.suspicion = obj_data['suspicion']
        group.is_actively_discovering_bases = obj_data.get('is_actively_discovering_bases', True)
        return group

    @property
    def id(self):
        return self.spec.id

    @property
    def name(self):
        return self.spec.name

    @property
    def suspicion_decay(self):
        return max(1, self.spec.suspicion_decay + self.changed_suspicion_decay)

    @property
    def discover_bonus(self):
        if not self.is_actively_discovering_bases:
            return 0
        return max(1, self.base_discover_bonus + self.changed_discover_bonus)

    @property
    def discover_suspicion(self):
        return max(1, (self.spec.discover_suspicion * (self.base_discover_suspicion + self.changed_discover_suspicion)) // 10000)

    @property
    def decay_rate(self):
        # Suspicion reduction is now quadratic.  You get a certain percentage
        # reduction, or a base .01% reduction, whichever is better.
        return max(1, (self.suspicion * self.suspicion_decay) // 10000)

    def new_day(self):
        self.alter_suspicion(-self.decay_rate)

    def alter_suspicion(self, change):
        self.suspicion = max(self.suspicion + change, 0)

    def alter_suspicion_decay(self, change):
        self.changed_suspicion_decay += change

    def alter_discover_bonus(self, change):
        self.changed_discover_bonus += change

    def alter_discover_suspicion(self, change):
        self.changed_discover_suspicion += change

    def discovered_a_base(self):
        self.alter_suspicion(self.discover_suspicion)

    def detects_per_day_to_danger_level(self, detects_per_day):
        raw_suspicion_per_day = detects_per_day * self.discover_suspicion
        suspicion_per_day = raw_suspicion_per_day - self.decay_rate

        # +1%/day or death within 10 days
        if suspicion_per_day > 100 \
           or (self.suspicion + suspicion_per_day * 10) >= 10000:
            return 3
        # +0.5%/day or death within 100 days
        elif suspicion_per_day > 50 \
           or (self.suspicion + suspicion_per_day * 100) >= 10000:
            return 2
        # Suspicion increasing.
        elif suspicion_per_day > 0:
            return 1
        # Suspicion steady or decreasing.
        else:
            return 0
