using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.ComponentModel;
using Aga.Controls.Tree;
using System.Drawing;
namespace pdfforge.DataStorageGenerator.DataGeneration
{
public enum ClassType
{
Class,
Struct
}
public class DataClass : IDataElement
{
private string name;
private List<IDataElement> values = new List<IDataElement>();
private Dictionary<string, string> customCode = new Dictionary<string, string>();
private bool _isReadOnly = false;
private ClassType _classType = ClassType.Class;
[Description("Set whether this class will be generated writable or read-only")]
public bool ReadOnly
{
get { return _isReadOnly; }
set { _isReadOnly = value; }
}
[DefaultValue(ClassType.Class), Description("Set the type of which the class will be generated")]
public ClassType ClassType
{
get { return _classType; }
set { _classType = value; }
}
[Description("The name of the class")]
public string Name
{
get { return name; }
set { name = value; }
}
[Browsable(false)]
public Image Icon
{
get
{
return new Bitmap(DataStorageGenerator.Properties.Resources.Class);
}
}
public DataClass(string name)
{
this.name = name;
}
public DataClass(XmlNode node)
{
this.name = node.Attributes["name"].Value;
if (this.name.Length == 0)
{
name = "NewClass";
}
foreach (XmlNode n in node.ChildNodes)
{
switch(n.Name) {
case "class":
xmlAddClass(n);
break;
case "value":
xmlAddValue(n);
break;
default:
throw new Exception("Unknown XML Node: " + n.Name);
}
}
}
private void xmlAddClass(XmlNode n)
{
try
{
DataClass val = new DataClass(n);
values.Add(val);
}
catch { }
}
private void xmlAddValue(XmlNode n)
{
string type = "";
try
{
type = n.Attributes["type"].Value;
}
catch { }
if (type != "")
{
DataValue val = null;
switch (type)
{
case "value":
val = new SimpleValue(n);
break;
default:
throw new Exception("Type not known");
}
values.Add(val);
}
}
public System.Collections.IEnumerable getChildren()
{
return values;
}
public bool hasChildren()
{
return values.Count > 0;
}
public bool propertyExists(string name)
{
foreach (IDataElement v in values)
{
if (v.getName().Equals(name))
return true;
}
return false;
}
public void addProperty(string name)
{
addProperty(new SimpleValue(name, DataType.String));
}
public void addProperty(DataValue value)
{
if (propertyExists(value.getName()))
throw new ArgumentException("A property with the name " + value.getName() + " already exists!");
values.Add(value);
}
public void addClass(DataClass value)
{
if (propertyExists(value.getName()))
throw new ArgumentException("A property with the name " + value.getName() + " already exists!");
values.Add(value);
}
public void addClass(string name)
{
DataClass c = new DataClass(name);
addClass(c);
}
public bool classExists(string name)
{
foreach (IDataElement e in values)
{
if (e is DataClass)
{
DataClass c = e as DataClass;
if (c.classExists(name))
return true;
}
}
return false;
}
public void collectSubClasses(List<DataClass> classes)
{
foreach (IDataElement e in values)
{
if (e is DataClass)
{
DataClass c = e as DataClass;
classes.Add(c);
c.collectSubClasses(classes);
}
}
}
public void removeElement(string name)
{
foreach (IDataElement v in values)
{
if (v.getName().Equals(name))
{
values.Remove(v);
return;
}
}
}
public string getName()
{
return name;
}
public IEnumerable<DataClass> getClasses()
{
List<DataClass> lst = new List<DataClass>();
foreach (IDataElement e in values)
{
if (e is DataClass)
lst.Add(e as DataClass);
}
return lst;
}
public void writeXml(XmlTextWriter textWriter)
{
textWriter.WriteStartElement("class");
textWriter.WriteStartAttribute("name");
textWriter.WriteString(name);
textWriter.WriteEndAttribute();
textWriter.WriteStartAttribute("readonly");
textWriter.WriteString(_isReadOnly.ToString());
textWriter.WriteEndAttribute();
textWriter.WriteStartAttribute("classtype");
textWriter.WriteString(_classType.ToString());
textWriter.WriteEndAttribute();
foreach (IDataElement value in values)
value.writeXml(textWriter);
textWriter.WriteEndElement();
}
public DataValue getProperty(string name)
{
foreach (DataValue v in values)
if (v.getName().Equals(name))
return v;
return null;
}
public List<string> getProperties()
{
List<string> myValues = new List<string>();
foreach (DataValue v in values)
{
myValues.Add(v.getName());
}
return myValues;
}
public void parseCurrentClass(string file) {
string start = "// START_CUSTOM_SECTION:";
string end = "// END_CUSTOM_SECTION";
if (!File.Exists(file))
return;
try
{
customCode.Clear();
string text = File.ReadAllText(file);
int pos = text.IndexOf(start);
int pos2;
int pos3;
string sectionName = "";
string sectionContent = "";
while (pos >= 0)
{
pos3 = text.IndexOf('\n', pos);
pos2 = text.IndexOf(end, pos);
sectionName = text.Substring(pos + start.Length, pos3 - pos - start.Length);
sectionName = sectionName.Trim();
sectionContent = text.Substring(pos3 + 1, pos2 - pos3 - 1);
if (sectionName != "")
{
customCode.Add(sectionName, sectionContent);
}
pos = text.IndexOf(start, pos2);
}
}
catch { }
}
private string getPropertyName()
{
string tmp = Name;
tmp = char.ToLower(tmp[0]) + tmp.Substring(1);
return tmp;
}
public void generatePropertyCS(ClassStringBuilder sb)
{
string tmp = getPropertyName();
sb.AppendLine("public " + Name + " " + tmp + " = new " + Name + "();");
}
public void generateLoadPropertyCS(ClassStringBuilder sb, string path)
{
string tmp = getPropertyName();
sb.AppendLine(tmp + ".readValues(data);");
}
public void generateSavePropertyCS(ClassStringBuilder sb, string path)
{
string tmp = getPropertyName();
sb.AppendLine(tmp + ".storeValues(data);");
}
/*public void generateCS(ClassStringBuilder sb)
{
generateCS(sb, Name + "\\", true);
}*/
public void generateCS(ClassStringBuilder sb, string path)
{
generateCS(sb, path + Name + "\\", "", path.Length == 0);
}
public void generateCS(ClassStringBuilder sb, string path, string nameSpace)
{
generateCS(sb, path + Name + "\\", nameSpace, path.Length == 0);
}
protected void generateCS(ClassStringBuilder sb, string path, string nameSpace, bool isRoot)
{
sb.AppendLine("using System;");
sb.AppendLine("using System.Collections.Generic;");
sb.AppendLine("using System.Text;");
sb.AppendLine("using pdfforge.DataStorage;");
addCustomCodeSection(sb, "INCLUDES", true);
sb.AppendLine("");
sb.AppendLine("// ! This file is generated automatically.");
sb.AppendLine("// ! Do not edit it outside the sections for custom code.");
sb.AppendLine("// ! These changes will be deleted during the next generation run");
sb.AppendLine("");
if (!String.IsNullOrEmpty(nameSpace))
{
sb.AppendLine("namespace " + nameSpace);
sb.AppendLine("{");
sb.incIndent();
}
sb.AppendLine("public class " + name + "{");
sb.incIndent();
if (isRoot)
{
sb.AppendLine("private Data data = Data.createDataStorage();");
sb.AppendLine("private DataReader dataReader = null;");
sb.AppendLine("private DataWriter dataWriter = null;");
}
sb.AppendLine();
foreach (IDataElement value in values)
{
value.generatePropertyCS(sb);
}
if (isRoot)
{
sb.AppendLine("");
sb.AppendLine("public " + name + "(DataReader dataReader, DataWriter dataWriter) {");
sb.incIndent();
sb.AppendLine("this.dataReader = dataReader;");
sb.AppendLine("this.dataWriter = dataWriter;");
sb.AppendLine("data = Data.createDataStorage();");
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine();
sb.AppendLine("public void setDataReader(DataReader dataReader) {");
sb.incIndent();
sb.AppendLine("this.dataReader = dataReader;");
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine();
sb.AppendLine("public void setDataWriter(DataWriter dataWriter) {");
sb.incIndent();
sb.AppendLine("this.dataWriter = dataWriter;");
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine("");
sb.AppendLine("public bool loadData(DataReader dataReader, string path) {");
sb.incIndent();
sb.AppendLine("try {");
sb.incIndent();
sb.AppendLine("data.clear();");
sb.AppendLine("dataReader.setData(data);");
sb.AppendLine("dataReader.readData(path);");
sb.AppendLine("readValues(data);");
sb.AppendLine("return true;");
sb.decIndent();
sb.AppendLine("} catch { return false; }");
sb.AppendLine();
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine("");
sb.AppendLine("public bool loadData(string path) {");
sb.incIndent();
sb.AppendLine("return loadData(dataReader, path);");
sb.AppendLine();
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine("");
sb.AppendLine("public bool saveData(DataWriter dataWriter, string path) {");
sb.incIndent();
sb.AppendLine("try {");
sb.incIndent();
sb.AppendLine("data.clear();");
sb.AppendLine("storeValues(data);");
sb.AppendLine("dataWriter.setData(data);");
sb.AppendLine("dataWriter.writeData(path);");
sb.AppendLine("return true;");
sb.decIndent();
sb.AppendLine("} catch { return false; }");
sb.AppendLine();
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine("");
sb.AppendLine("public bool saveData(string path) {");
sb.incIndent();
sb.AppendLine("return saveData(dataWriter, path);");
sb.AppendLine();
sb.decIndent();
sb.AppendLine("}");
}
sb.AppendLine();
sb.AppendLine("public void readValues(Data data) {");
sb.incIndent();
foreach (IDataElement value in values)
{
value.generateLoadPropertyCS(sb, path);
}
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine("");
sb.AppendLine("public void storeValues(Data data) {");
sb.incIndent();
foreach (IDataElement value in values)
{
value.generateSavePropertyCS(sb, path);
}
sb.decIndent();
sb.AppendLine("}");
sb.AppendLine("");
addCustomCodeSection(sb, "GENERAL", true);
foreach (KeyValuePair<string, string> section in customCode)
{
addCustomCodeSection(sb, section.Key, false);
}
// Close Class
sb.decIndent();
sb.AppendLine("}");
// Close namespace
if (!String.IsNullOrEmpty(nameSpace))
{
sb.decIndent();
sb.AppendLine("}");
}
}
/// <summary>
/// Adds a custom code section to the generated class. Things that are inserted in these sections will not be removed during a regeneration
/// </summary>
/// <param name="sb">The current StringBuilder</param>
/// <param name="section">Name of the code section</param>
/// <param name="delete">If false, the section will not be rermoved from the section list and will be added again on the bottom of the file</param>
private void addCustomCodeSection(ClassStringBuilder sb, string section, bool delete)
{
string code;
if (customCode.TryGetValue(section, out code))
{
if (delete)
customCode.Remove(section);
}
else
code = "";
int indent = sb.getIndent();
sb.setIndent(0);
sb.AppendLine("// Custom Code starts here");
sb.AppendLine("// START_CUSTOM_SECTION:" + section);
sb.Append(code);
sb.AppendLine("// END_CUSTOM_SECTION:" + section);
sb.AppendLine("// Custom Code ends here. Do not edit below");
sb.setIndent(indent);
sb.AppendLine();
}
}
}