/*
 * Scone - The Web Enhancement Framework
 * Copyright (C) 2009 Harald Weinreich, Volkert Buchmann, Frank Wollenweber, Torsten Haß
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package scone.accesstracking;

import scone.netobjects.NetNode;
import scone.proxy.HtmlTokenEditor;
import scone.util.tokenstream.HtmlTagToken;
import scone.util.tokenstream.HtmlTextToken;
import scone.util.tokenstream.SconePipe;
import scone.util.tokenstream.Token;
import scone.util.tokenstream.TokenInputStream;
import scone.util.tokenstream.TokenOutputStream;


/**
 * Adds line in header to get JavaScript code from AccessTrackingMeg, which tracks user actions.<P>
 *
 * The following Code is inserted if the page ist not the head of a frameset: <BR>
 * &lt;SCRIPT Language='JavaScript1.2' SRC='http://tracking.scone.de/_id123'&gt;&lt;/SCRIPT&gt; where 123 is the nodeId<P>
 *
 * In case of a frameset a special piece of JavaScript code is inserted instead. This piece tests if 
 * the window already has a name. If not, a name is generated. That is necessary if a browser
 * window starts with a frameset.<br>
 *
 * The following Code is inserted in case of a frameset: <BR>
 * &lt;SCRIPT type='text/javascript'&gt;<br>
 * &lt;!--<br>
 * if (!window.name) { window.name = 'SCONE'+_scone_start_time+Math.floor(Math.random()*10000)};<br>
 * //--&gt;<br>
 * &lt;/SCRIPT&gt;
 * @author Harald Weinreich
 * @author Volkert Buchmann
 * @author Torsten Hass
 */
public class JavaScriptAdder extends HtmlTokenEditor {

    public static final String COPYRIGHT = "(C) Harald Weinreich & Volkert Buchmann";

    /**
     * tries to add the preamble:
     * <OL>
     * <LI> before &lt;/head&gt;-Tag
     * <LI> before &lt;body&gt;-Tag
     * <LI> before &lt;frameset&gt;-Tag
     * <LI> before heading
     * <LI> before table
     * <LI> before link (&lt;A&gt; or &lt;AREA&gt;-Tag
     * <LI> before image
     * <LI> before form
     * <LI> before preformatted text
     * </OL>
     * In case of a frameset a special JavaScript code is added to generate a window name if
     * the window has none.
     */

    public void handleRequest(SconePipe pipe) {
        try {
            TokenInputStream in = pipe.getTokenInputStream();
            TokenOutputStream out = pipe.getTokenOutputStream();

            String nodeId = ((NetNode) in.getMetaInfo().get("baseNode")).getNodeId();

            // get the Postdata of a submitted form and write it into a JavaScript variable
            //System.out.println("Post-data (javaScriptAdder): "+in.getMetaInfo().get("postData"));
            String postDataVar = "var postData='';";
            if (in.getMetaInfo().get("postData") != null) {     // if there is posted data
                postDataVar = (String)in.getMetaInfo().get("postData");
                if (postDataVar.endsWith("\n")) {               // look for a "/n" at the end of the postdata string
                    postDataVar = postDataVar.substring(0,postDataVar.length()-1);
                }
                postDataVar = "var postData='"+postDataVar.substring(0,postDataVar.length()-1) +"';"; // write it into a JavaScript variable
            }
            boolean written = false;
            boolean frameset = false;
            Token t = null;
            HtmlTagToken tag = null;
            HtmlTextToken postDataAdder = new HtmlTextToken("\n<script type='text/javascript'>\n<!--\n"+postDataVar+"\n//-->\n</script>\n");
            HtmlTextToken preamble = new HtmlTextToken("\n<SCRIPT Language='JavaScript1.2' SRC='http://tracking.scone.de/_id" + nodeId + "' type='text/javascript'></SCRIPT>\n");   // must be same host!!!
            HtmlTextToken scriptForFrameset = new HtmlTextToken("\n<SCRIPT type='text/javascript'>\n<!--\nif ((!window.name) || (window.name=='_blank')) { window.name = 'SCONE'+_scone_start_time+Math.floor(Math.random()*10000)};\n//-->\n</SCRIPT>\n");

            while ((t = in.read()) != null) {

                if (!written && (t instanceof HtmlTagToken)) {
                    tag = (HtmlTagToken) t;
                    if (tag.getTagType() == tag.T_FRAMESET) { // test if Frameset tag appears
                        out.write(scriptForFrameset); // write JavaScript that creates a frame name,
                    }                                // this is necessary if Browser starts with Frameset

                    if (/*
                             ( (tag.getTagType()==tag.T_HEAD) && (tag.isEndTag()) ) ||*/
                            // (tag.getTagType()==tag.T_SCRIPT) ||  //before any other JavaScript Code!
                            (tag.getTagType() == tag.T_BODY) ||    // the body is about to start...
                            (tag.getTagType() == tag.T_H1) ||      // Headings
                            (tag.getTagType() == tag.T_H2)
                            || (tag.getTagType() == tag.T_H3)
                            || (tag.getTagType() == tag.T_H4)
                            || (tag.getTagType() == tag.T_H5)
                            || (tag.getTagType() == tag.T_H6)
                            || (tag.getTagType() == tag.T_TABLE)
                            || (tag.getTagType() == tag.T_A) ||      // Link
                            (tag.getTagType() == tag.T_AREA)
                            || (tag.getTagType() == tag.T_IMG) ||     // Image
                            (tag.getTagType() == tag.T_FORM) ||    // Form
                            (tag.getTagType() == tag.T_PRE))      // Preformatted
                    {
                        if (!frameset) {
                            out.write(postDataAdder);   // write JavaScript code that contains posted data
                            out.write(preamble);        // write script tag to load external JavaScript file
                        }
                        written = true;
                    }
                }
                out.write(t);
            }
        } catch (Exception exc) {
            exc.printStackTrace();

        }
    }

}
