# Copyright (C) 2017 Bran Seals. All rights reserved.
# Created: 2017-06-06

class UmlClass:
    def __init__(self, className):
        self.name = className
        self.hppPrivate = ["private:"]
        self.hppPublic = ["public:"]
        self.cpp = [ # will contain final version of cpp file
            "// Copyright (C) 2016. All rights reserved.",
            "// Created: ", # add creation date
            "",
            "#include \"" + self.name + ".hpp\"", 
        ]
        self.hpp = [ # will contain final version of hpp file
            "// Copyright (C) 2016. All rights reserved.",
            "// Created: ", # add creation date
            "",
            "#ifndef " + self.name + "_hpp", 
            "#define " + self.name + "_hpp",
            "",
            "class " + self.name,
            "{",
            "};",
            "#endif"
        ]

    indent = "    " # soft tab size 4

    def addToPublic(self, pubMember): # adds given string to public scope list
        self.hppPublic.append(pubMember)

    def addToPrivate(self, privMember): # adds given string to private scope list
        self.hppPrivate.append(privMember)

    def isFunction(self, line):
        if "(" in line and ")" in line and "(C)" not in line:
            return True

    def includeLibs(self): # include libraries for data types that need them
        
        # Data types being searched
        stringFound = False
        vectorFound = False

        # Search for types with required libraries
        for line in self.hpp:
            if "std::string" in line:
                stringFound = True
            if "std::vector" in line:
                vectorFound = True

        # Include libraries, along with extra space if found
        if stringFound:
            self.hpp[self.hpp.index("class " + self.name):1] = ["#include <string>"]
        if vectorFound:
            self.hpp[self.hpp.index("class " + self.name):1] = ["#include <vector>"]
        if stringFound or vectorFound:
            self.hpp[self.hpp.index("class " + self.name):1] = [""]

    def buildHpp(self):
        # Insert public members after {, where class begins
        self.hpp[self.hpp.index("{")+1:1] = self.hppPublic

        # Insert private members after last public member
        self.hpp[self.hpp.index(self.hppPublic[-1])+1:1] = self.hppPrivate

    def formatHpp(self):
        self.moveReturnType()
        self.includeLibs()
        self.addNamespace()
        self.indentAndSemiColon()

    def build(self):
        self.buildHpp()
        self.formatHpp()
        self.buildCpp()
        self.formatCpp()

    def addNamespace(self):
        for line in self.hpp:
            i = self.hpp.index(line)
            if "string" in line:
                line = line.replace("string", "std::string", 1)
                self.hpp[i] = line
            if "vector" in line:
                line = line.replace("vector", "std::vector", 1)
                self.hpp[i] = line

    def moveReturnType(self):
        for line in self.hpp:
            i = self.hpp.index(line)
            if " : " in line:
                line = line[line.index(":")+1:].strip() + " " + line[:line.index(":")].strip()
                self.hpp[i] = line

    def isMember(self, line):
        notMember = ["/", "#", "class ", "{", "}", "public:", "private:", "protected:", "return"]
        if any(notM in line for notM in notMember) or line == "":
            return False
        else:
            return True

    def indentAndSemiColon(self):
        for line in self.hpp:
            i = self.hpp.index(line)
            if self.isMember(line):
                line = self.indent + line + ";"
                self.hpp[i] = line

    def buildCpp(self):
        for line in self.hpp:
            if (self.isFunction(line)):
                self.cpp.append(line[len(self.indent):-1]) # remove indent and ;

    def formatCpp(self):
        for line in self.cpp:
            i = self.cpp.index(line)
            if self.isMember(line):
                
                # Search and insert className::
                splitLine = line.split()
                for bit in splitLine:
                    j = splitLine.index(bit)
                    if "(" in bit:
                        bit = self.name + "::" + bit
                        splitLine[j] = bit
                if len(splitLine) > 1:
                    line = " ".join(splitLine)
                else:
                    line = "".join(splitLine)

                # Add function body
                line = line + "\n{\n" + self.indent + "return;\n}\n"
                self.cpp[i] = line

    def createFiles(self):
        self.build()

        # Create .hpp
        self.hppFile = open(self.name + ".hpp", "w")
        for line in self.hpp:
            self.hppFile.write(line + "\n")
        self.hppFile.close()

        # Create .cpp
        self.cppFile = open(self.name + ".cpp", "w")
        for line in self.cpp:
            self.cppFile.write(line + "\n")
        self.cppFile.close()
@@ -68,16 +68,42 @@
 17-06-06
+%0Afrom datetime import date
 %0A%0Aclass 
@@ -400,37 +400,37 @@
 eated: %22
-, # add creation date
+ + str(date.today()),
 %0A       
@@ -650,29 +650,29 @@
 d: %22
-, # add creation date
+ + str(date.today()),
 %0A   
@@ -4055,54 +4055,211 @@
     
-%0A                # Search and
+line = self.insertClassName(line)%0A                # Add function body%0A                line = %22%5Cn%22 + line + %22%5Cn%7B%5Cn%22 + self.indent + %22return;%5Cn%7D%22%0A                self.cpp%5Bi%5D = line%0A%0A    def
  insert
- c
+C
 lassName
 ::%0A 
@@ -4258,19 +4258,62 @@
 Name
-::%0A        
+(self, line):%0A        # Search and insert className::%0A
     
@@ -4349,24 +4349,16 @@
         
-   
-     
 for bit 
@@ -4367,32 +4367,24 @@
  splitLine:%0A
-        
             
@@ -4416,32 +4416,24 @@
             
-        
 if %22(%22 in bi
@@ -4435,24 +4435,16 @@
 in bit:%0A
-        
         
@@ -4496,24 +4496,16 @@
         
-        
 splitLin
@@ -4523,24 +4523,16 @@
         
- 
-       
 if len(s
@@ -4554,32 +4554,24 @@
             
-      
-  
 line = %22 %22.j
@@ -4581,32 +4581,24 @@
 (splitLine)%0A
-        
         else
@@ -4607,32 +4607,24 @@
             
-   
-     
 line = %22%22.jo
@@ -4641,143 +4641,22 @@
 ne)%0A
-%0A                # Add function body%0A                line = line + %22%5Cn%7B%5Cn%22 + self.indent + %22return;%5Cn%7D%5Cn%22%0A                self.cpp%5Bi%5D =
+        return
  lin

Add creation date and insertClassName