#!/usr/bin/env python3
"""
 September 22, 2004, Dr. Brian Fristensky, University of Manitoba

 Description: Convert a GDE flatfile into another format 

 Synopsis: flatcnv.py infile outfile

 Files: infile      GDE flat file, with name on line 1, followed by

                   comma separated list of tokens GI numbers

       outfile     GDE flat file, with name on line 1, followed by

                   comma-separated list of integers 

@modified: May 26 2010
@author: Dale Hamel
@contact: umhameld@cc.umanitoba.ca
"""

import sys
import os
import sys

blib = os.environ.get("BIRCHPYLIB")
sys.path.append(blib)

from birchlib import Birchmod
from birchlib import Argument

PROGRAM = "flatcnv.py : "
USAGE = "\n\tUSAGE: flatcnv.py [options] infile outfile"
BM = Birchmod(PROGRAM, USAGE)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class Parameters:
    "Wrapper class for command line parameters"
    def __init__(self):
        """
     	  Initializes arguments:
     		IFN=""
     		OFN=""
     		OUTTYPE=""
     	  Then calls read_args() to fill in their values from command line
          """
        self.IFN = ""
        self.OFN = ""
        self.OUTTYPE = ""
        self.read_args()
	
    def read_args(self):
        """
		Read command line arguments into a Parameter object
		"""

        is_list = Argument("-list", None, BM)

	
        length = len(sys.argv)
	
        infile = Argument("", str, BM)
        outfile = Argument("", str, BM)
	
        infile.set_position(length-2)
        outfile.set_position(length-1)
	
        is_list.set_optional()
        is_list.add_exclusive("-csv")
		

	
	
        try:
            self.IFN = infile.fetch()
            self.OFN = outfile.fetch()
		
            if(is_list.fetch()):
                print(PROGRAM + "providing output in list format")
                self.OUTTYPE = "list"
            else:
                print(PROGRAM + "providing output in csv format")
                self.OUTTYPE = "csv"
		
        except ValueError:
            BM.printusage()
	
	
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class FILE:
    "Wrapper class for files"
     
    def __init__(self, FILENAME, MODE):
        """
          @param FILENAME: The name of the file
          @type FILENAME: str
          @param MODE: Type of file operation (read/write)
          @type MODE:str : (r, w, rw)
          """
        self.FN = FILENAME
	  
        self.LINE = "" # most recent line read
        try:
            self.F = open(FILENAME, MODE)
	  	
        except:
            BM.fileError(FILENAME)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class IDLST:
    "Wrapper class for ID lists"
     
    def __init__(self):
        """
          FIXME
          """
        self.NAME = ""
        self.LST = []
	  	  
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

def GETGDELIST(INFILE, NAMEFLAG, L):
    """
    Read in old and new strings, striping 
    leading and trailing whitespace, including
    newline characters.
    """
    # Read name line
    while (INFILE.LINE != "" and L.NAME == "") :
          INFILE.LINE = INFILE.LINE.strip()
	  if len(INFILE.LINE) > 0 :
             if INFILE.LINE[0] == NAMEFLAG :
                L.NAME = INFILE.LINE[1:]
          INFILE.LINE = INFILE.F.readline()	
          	  
    
    # Read GI list 
    L.LST = []   
    if L.NAME != "":
        # GDE wraps the flat file with newlines every 60
        # characters.
        # Next, we have to delete the newlines to turn the entire
        # file into a single long string called BIGLINE
        BIGLINE = ""
        # Python 2.3 introduced a boolean type, but we'll do it
        # the crude way for backward compatability.

       DONE =  0     
       while (INFILE.LINE != "" and DONE == 0) :
             TMPLINE = INFILE.LINE.strip()
	     if len(TMPLINE) > 0 :
	        if TMPLINE[0] == NAMEFLAG :
		   DONE = 1
	        else:
		   BIGLINE = BIGLINE + TMPLINE
	           INFILE.LINE = INFILE.F.readline()
	          

        # parse the string as a comma separated list
        L.LST = BIGLINE.split(',')

    return


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

def WRITECSVFILE(F, L):
    """
    Write the list as a single line of comma-separated values
    """	
    # Write name
    if L.NAME != "":
        F.write(L.NAME)
    # Write list
    LEN = len(L.LST)
    if  LEN > 0:
        F.write(',')
        for i in range(0, LEN):
            F.write(L.LST[i])
            if i < LEN-1:
                F.write(",")
    F.write('\n')
	      
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

def WRITENAMEFILE(F, LST):
    """
    Write the list with one item per line
    """	
    if len(LST) > 0:
        for i in range(0, len(LST)):
            LINE = LST[i].strip()
            if LINE != "":
                LINE = LINE + '\n'
                F.write(LINE)
	      
	        
#======================== MAIN PROCEDURE ==========================


def main():
    """
 	Called when not in documentation mode.
 	"""
#---------- Set global variables	
P = Parameters ()


NAMEFLAG = '"'  # 1st character on the name line, indicating
    # the beginning of the next data list

INFILE = FILE(P.IFN, 'r')
OUTFILE = FILE(P.OFN, 'w')
	
	
INFILE.LINE = INFILE.F.readline() # LINE contains the most recently-read line

while (INFILE.LINE != "") :

   # Read in GDE flat file
   L = IDLST()
   GETGDELIST(INFILE,NAMEFLAG,L)
      
   #Write the list
   if P.OUTTYPE == "list" :
      WRITENAMEFILE(OUTFILE.F,L.LST)
   else :
      WRITECSVFILE(OUTFILE.F,L)

	
    INFILE.F.close()
    OUTFILE.F.close()
	
    BM.exit_success()

if (BM.documentor() or "-test" in sys.argv):
    pass
else:
    main()
