/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cz.muni.fi.mias.math;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Container class for the information about a single MathML formula
 * 
 * @author Martin Liska
 */
public class Formula {

    private float weight;
    private Node node;
    private String miasString;

    public Formula() {
    }

    public Formula(Node node, float weight) {
        this.weight = weight;
        this.node = node;
    }
    
    public Formula(Formula f) {
        this.node = f.getNode().cloneNode(true);
        this.weight = f.getWeight();
    }

    public String getMiasString() {
        return miasString;
    }

    public void setMiasString(String miasString) {
        this.miasString = miasString;
    }
    
    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }

    public Node getNode() {
        return node;
    }

    public void setNode(Node node) {
        this.node = node;
    }

    @Override
    public String toString() {
        return "Formula{" + "weight=" + weight + "node=" + nodeToString(node, false, new HashMap<String, String>(), new HashMap<String, String>(), new ArrayList<String>()) + '}';
    }
    
    /**
     * Creates M-term styled string representation of a MathML formula.
     * 
     * @param node MathML with the formula
     * @param withoutTextContent if true, resulting string will not contain text content of MathML nodes
     * @param eldict dictionary for substituting standard MathML element names for custom ones
     * @param attrdict dictionary for substituting standard MathML attribute names and their values for custom ones
     * @param ignoreNode a list of MathML nodes which the output should not contain
     * @return M-terms styles string representing the input MathML formula
     */
    public static String nodeToString(Node node, boolean withoutTextContent, Map<String, String> eldict, Map<String, String> attrdict, List<String> ignoreNode) {
        String s = "";
        if (node instanceof Element) {
            String name = node.getLocalName() != null ? node.getLocalName() : node.getNodeName();
            if (!ignoreNode.contains(name)) {
                if (eldict.get(name) == null || withoutTextContent) {
                    s += name;
                } else {
                    s += eldict.get(name);
                }
                if (!withoutTextContent) {
                    NamedNodeMap attrs = node.getAttributes();
                    for (int i = 0; i < attrs.getLength(); i++) {
                        String attrName = attrs.item(i).getNodeName();
                        if (attrdict.containsKey(attrName)) {
                            String dictAttrName = attrdict.get(attrName);
                            String attrValue = attrs.item(i).getNodeValue();
                            String dictValue = attrdict.get(attrValue);
                            s += "[" + dictAttrName + "=" + (dictValue == null ? attrValue : dictValue) + "]";
                        }

                    }
                }
                NodeList nl = node.getChildNodes();
                int length = nl.getLength();
                if ((length > 1)) {
                    s += "(";
                    for (int j = 0; j < length; j++) {
                        s += nodeToString(nl.item(j), withoutTextContent, eldict, attrdict, ignoreNode);
                    }
                    s += ")";
                } else {
                    if (name.equals("mrow") || name.equals("math") || name.equals("mfenced")) {
                        if (length == 1) {
                            s = nodeToString(node.getFirstChild(), withoutTextContent, eldict, attrdict, ignoreNode);
                        } else {
                            s = "";
                        }
                    } else if (!withoutTextContent) {
                        s += "(" + node.getTextContent() + ")";
                    }
                }
            }
        }
        return s;
    }
}

@@ -548,16 +548,66 @@
 sString;
+%0A    private static final int LENGTH_TRIM = 20000;
 %0A%0A    pu
@@ -2329,23 +2329,47 @@
   String
- s = %22%22
+Builder s = new StringBuilder()
 ;%0A      
@@ -2640,16 +2640,21 @@
    s
- += 
+.append(
 name
+)
 ;%0A  
@@ -2697,20 +2697,24 @@
        s
- += 
+.append(
 eldict.g
@@ -2717,24 +2717,25 @@
 ct.get(name)
+)
 ;%0A          
@@ -3303,39 +3303,60 @@
    s
- += %22%5B%22 + dictAttrName + %22=%22 + 
+.append(%22%5B%22).append(dictAttrName).append(%22=%22).append
 (dic
@@ -3398,14 +3398,20 @@
 lue)
- + 
+.append(
 %22%5D%22
+)
 ;%0A  
@@ -3629,23 +3629,28 @@
        s
- += 
+.append(
 %22(%22
+)
 ;%0A      
@@ -3723,20 +3723,24 @@
        s
- += 
+.append(
 nodeToSt
@@ -3797,32 +3797,33 @@
 ict, ignoreNode)
+)
 ;%0A              
@@ -3855,15 +3855,20 @@
    s
- += 
+.append(
 %22)%22
+)
 ;%0A  
@@ -4058,19 +4058,24 @@
        s
- = 
+.append(
 nodeToSt
@@ -4150,16 +4150,17 @@
 oreNode)
+)
 ;%0A      
@@ -4222,10 +4222,27 @@
 s = 
-%22%22
+new StringBuilder()
 ;%0A  
@@ -4348,18 +4348,28 @@
    s
- += %22(%22 + 
+.append(%22(%22).append(
 node
@@ -4389,14 +4389,21 @@
 nt()
- + 
+).append(
 %22)%22
+)
 ;%0A  
@@ -4476,16 +4476,125 @@
     
-return s
+if (s.length() %3E LENGTH_TRIM) %7B%0A            return s.substring(0, LENGTH_TRIM);%0A        %7D%0A        return s.toString()
 ;%0A  

Use StringBuilder for nodeToString, trim Formula string to length 20000