class ccp4idb:
    """CCP4i job database object"""

    # Initialise a new project database
    def __init__(self,project,directory):
        self.__projectname = project
        self.__directory = directory
        self.__joblist = []

    # By default report the project name
    def __repr__(self):
        return self.projectname()

    # Load data from file and set up lock
    def load(self):
        print self.projectname()+": loading data from directory "+ \
        self.directory()+" (not implemented)"

    # Retreive the data
    # Project name
    def projectname(self):
        return self.__projectname
    # Directory where hardcopy of data resides
    def directory(self):
        return self.__directory
    # List of jobs
    def joblist(self):
        return self.__joblist
    # Number of jobs
    def njobs(self):
        return len(self.joblist())
    
    # Add a job
    def newjob(self,taskname,title):
        newjob = ccp4ijob(self.njobs(),taskname,title)
        joblist = self.joblist()
        joblist.append(newjob)
        return newjob

    # Retrieve handle for particular job id
    def findjob(self,job_id):
        # Loop over jobs until you find the one
        # you want
        for job in self.joblist():
            if job.getId() == job_id:
                return job
        else:
            # Id wasn't matched
            return ccp4ijob()
        
    # List database information
    def display(self):
        print "Name : "+str(self.projectname())
        print "Dir  : "+str(self.directory())
        print "Njobs: "+str(self.njobs())
        # Iterate over jobs and invoke display for each
        for job in self.joblist():
            job.display()

class ccp4ijob:
    """CCP4i job object holding a run of a task"""

    # Data
    job_id   = 0
    title    = ""
    taskname = ""
    status   = ""
    null_job = True
    # Store arbitrary key-value pairs in a dictionary
    __data   = {}

    # Define default constructor
    def __init__(self,job_id = 0,taskname = "",title = ""):
        self.job_id = job_id
        self.taskname = taskname
        if job_id >= 0 and taskname != "":
            self.title  = title
            self.status = "STARTING"
            self.null_job = False
            # Dictionary for storing arbitrary key/value pairs
            self.__data = {}
        else:
            self.null_job = True    

    # By default report the job id
    def __repr__(self):
        if not self.isnull():
            return str(self.job_id)
        else:
            return str(-1)

    # Check if job is "null"
    def isnull(self):
        return self.null_job

    # Retrieve taskname
    def getTaskname(self):
        if (not self.isnull()):
            return self.taskname
        else:
            return "(null job)"

    # Set/retrieve title
    def setTitle(self,newtitle):
        self.title = newtitle
    def getTitle(self):
        return self.title

    # Set/retrieve arbitrary data
    def setData(self,key,value):
        if not self.isnull():
            self.__data[str(key)]=str(value)
    def getData(self,key):
        if not self.isnull() and self.exists(str(key)):
            return self.__data[str(key)]
        else:
            return "(key doesn't exist)"
    def exists(self,key):
        return self.__data.has_key(str(key))

    # Get job id
    def getId(self):
        return self.job_id

    # Validation
    # This should be performed against some template
    def iscomplete(self):
        # Check that the job has values for all
        # attributes
        if self.isnull:
            return False
        if self.job_id == "":
            return False
        if self.taskname == "":
            return False
        if self.status == "":
            return False
        return True

    # Display job information
    def display(self):
        if not self.isnull():
            print str(self.job_id)+"\t:"+ \
                  str(self.status)+"\t"+ \
                  str(self.taskname)+"\t\""+ \
                  str(self.title)+"\""
            print self.__data
        else:
            print "(null job)"

######################################################################
# Read a file
def readfile(filename):
    """read_def_file(string)"""
    try:
        f = open(str(filename),"r")
    except:
        # Catch all errors
        print "read_def_file: error opening file \"%s\"" % str(filename)
        # Pass the error on to the calling subprogram
        raise
    # File should be open - read a line at a time
    for line in f:
        # Ignore comment lines - this is not very clever e.g.
        # can't account for leading spaces
        if line[0] == "#":
            print "Comment line (ignored)"
            continue
        # Strip trailing newline character
        if line[-1] == "\n":
            line = line[:-1]
        # Echo the line to stdout
        print "Line:", line
    # Close the file
    f.close()
