"""Common functions and objects used by demo_durus.py and demo_sqlalchemy.py

Updated: 2007-09-12 by Mike Orr.  Public domain.
"""
from durus.persistent import Persistent

class Flintstone(object):
    def __init__(self, name, sex, pastime):
        self.name = name
        self.sex = sex
        self.pastime = pastime
    
    def __repr__(self):
        tup = self.name, self.sex, self.pastime
        return "<Flintstone name='%s' sex='%s' pastime='%s'>" % tup

    def __cmp__(self, other):
        """Default sort is by name."""
        if not isinstance(other, Flintstone):
            return NotImplemented
        return cmp(self.name, other.name)
            
    
class PFlintstone(Flintstone, Persistent):
    pass

### Report stuff

class ReportModel(object):
    """Database-specific helper for Report class."""
    
    def exists(self, who):
        """Return true if the person named 'who' is in the database."""
        raise NotImplementedError("subclass responsibility")
    
    def get_women_names(self):
        """Return a list of names of all women in the database."""
        raise NotImplementedError("subclass responsibility")
    
    def get_roster(self):
        """Return a list of objects of all people in the database.
           Each object must have a .name, .sex, and .pastime attribute, all strings.
        """
        raise NotImplementedError("subclass responsibility")
    
    def get_bam_bam_pastime(self):
        """Return Bam-Bam's pastime as a string."""
        raise NotImplementedError("subclass responsibility")
    
    def count_sex(self, sex):
        """Return the number of 'sex' residents in the database.
           'sex' is a string ("M", "F").
        """
        raise NotImplementedError("subclass responsibility")
    
    def sex_change_all_men(self):
        """Change all men's sex to female.  Do not do DB commit."""
        raise NotImplementedError("subclass responsibility")
        
    def sex_change_undo(self):
        """Undo all sex-change operations."""
        raise NotImplementedError("subclass responsibility")
    

class Report(object):
    def __init__(self, model):
        self.model = model
    
    def main(self):
        self.begin()
        self.print_exists("Fred")
        self.print_exists("Barney")
        self.print_women()
        self.print_roster()
        self.print_bam_bam_pastime()
        self.modify_database_example()
        self.end()
    
    
    ### Report section methods
    def begin(self):
        pass
    
    def print_exists(self, who):
        if self.model.exists(who):
            print "%s exists." % who
        else:
            print "%s does not exist." % who
            
    def print_women(self):
        names = self.model.get_women_names()
        names = ", ".join(names)
        print "The women in the Flintstone neighborhood are: %s." % names
        
    def print_bam_bam_pastime(self):
        pastime = self.model.get_bam_bam_pastime()
        print "Bam-Bam's pastime is %s." % pastime

    def print_roster(self):
        flintstones = self.model.get_roster()
        header    = "Name         Sex Pastime             "
        separator = "------------+---+--------------------"
        print "Full roster of residents:"
        print header
        print separator
        for flint in flintstones:
            print "%-12s|%-3s|%-24s" % (flint.name, flint.sex, flint.pastime)
        print separator
        
    def modify_database_example(self):
        self.print_sex_distribution()
        print "Fred decides to get a sex-change operation."
        self.model.sex_change_fred()
        self.print_sex_distribution()
        print "All the men in the neighborhood decide to do the same."
        self.model.sex_change_all_men()
        self.print_sex_distribution()
        print "Then the men have second thoughts and switch back."
        self.model.sex_change_undo()
        self.print_sex_distribution()
        
    def print_sex_distribution(self):
        men = self.model.count_sex("M")
        women = self.model.count_sex("F")
        print "Neighborhood census: %d men, %d women" % (men, women)
        
    def end(self):
        print "End of demo."
        print


