package com.quantum.model.xml;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.sql.Types;

import com.quantum.model.Bookmark;
import com.quantum.model.Column;
import com.quantum.model.Entity;
import com.quantum.model.NotConnectedException;
import com.quantum.model.Schema;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @author BC
 */
public class TorqueConverter {
    public void createRoot(Document document) {
        Element root = document.createElement("database");
        document.appendChild(root);
    }
    public void convert(Element root, Bookmark bookmark, Schema schema) {
        try {
            Entity[] tables = bookmark.getEntitiesForSchema(
                schema, Entity.TABLE_TYPE);
                
            for (int i = 0, length = (tables == null) ? 0 : tables.length;
                i < length;
                i++) {
                convert(root, tables[i]);
            }
        } catch (SQLException e) {
        }
    }

    public void convert(Element root, Entity entity) {
        Element table = root.getOwnerDocument().createElement("table");
        table.setAttribute("name", entity.getName());
        
		try {
			Column[] columns = entity.getColumns();
			for (int i = 0, length = (columns == null) ? 0 : columns.length;
	            i < length;
	            i++) {
	            convert(table, columns[i]);
	        }
		} catch (NotConnectedException e) {
		} catch (SQLException e) {
		}
        
        root.appendChild(table);
    }

    public void convert(Element root, Column column) {
        Element element = root.getOwnerDocument().createElement("column");
        element.setAttribute("name", column.getName());
        if (column.isPrimaryKey()) {
            element.setAttribute("primaryKey", "true");
        }
        element.setAttribute("required", column.isNullable() ? "false" : "true");
        if (column.isNumeric() && column.getNumberOfFractionalDigits() > 0) {
            element.setAttribute("size", String.valueOf(column.getSize()) + 
                "," + String.valueOf(column.getNumberOfFractionalDigits()));
        } else if (column.getSize() >= 0) {
            element.setAttribute("size", String.valueOf(column.getSize()));
        }
        element.setAttribute("type", getStandardType(column.getType()));
        
        root.appendChild(element);
    }
    
    private String getStandardType(int type) {
        String result = null;
        try {
            Field[] fields = Types.class.getFields();
            for (int i = 0, length = (fields == null) ? 0 : fields.length;
                result == null & i < length;
                i++) {
                if (fields[i].getDeclaringClass() == Integer.TYPE &&
                    Modifier.isStatic(fields[i].getModifiers()) &&
                    Modifier.isPublic(fields[i].getModifiers()) &&
                    type == fields[i].getLong(null)) {
                    
                    result = fields[i].getName();
                }
            }
        } catch (IllegalAccessException e) {
            // shouldn't happen
        }
        return result;
    }
}