/*
 * 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.accesstracking2;


import java.util.ArrayList;

import scone.netobjects.Access;


/**
 * Keeps the history of one Window/Frame of a Web-browser to amalyse the
 * movements of the user.
 *
 * @author Torsten Hass
 * @version 1.0b, 11/02/2001
 */

public class FrameHistory {
    private final static int NEWURL = scone.accesstracking2.EventDecoder.NEWURL;   // could not find out the way of opening this page

    private ArrayList accessList; // stores Access and Framset
    private int position = 0;     // current position in history
    private int lastAction;       // action that made the browser load next page
    private int lastLinkType;       // Type of last link...
    private String lastReferrer;       // action that made the browser load next page
    private String lastLinkPos;       // position of link on page
    private String lastWindowSize;       // Size of window
    private String lastLinkAnchor;       // Link Anchor Text
    private String lastLinkTitle;       // Title attribute of link

    public FrameHistory() {
        accessList = new ArrayList();
        position = 0;
        lastAction   = NEWURL;
        lastReferrer = "";
    }

    /**
     * Adds the new Access object to history list.
     *
     * @param megTime The time when the JavaScriptCode was generated
     * @param a The Access object to add to list
     */
    public void add(Access a) {
        // System.out.println("FrameHistory: add("+a.toString()+")");
        accessList.add(a);
        position = accessList.size()-1;
    }


    /**
     * Checks if the given Access object matches one in the FrameHistory
     * in following fields:<br>
     * userId, nodeId, frameName, fragment, query<br>
     *
     * @param a The Access object
     * @return <code>true</code> if "a" matches one in the FrameHistory
     */
    public boolean contains(Access a) {
        int counter;
        boolean result = false;
        Access a1;

        for (counter = 0; counter < accessList.size(); counter++) {
                a1 = (Access) accessList.get(counter);
                if (a1.getUserId().equals(a.getUserId())
                        && a1.getNodeId().equals(a.getNodeId())
                        && a1.getFrameName().equals(a.getFrameName())
                        && a1.getFragment().equals(a.getFragment())
                        && a1.getQuery().equals(a.getQuery())
                        && a1.getParentFrameNodeId().equals(a.getParentFrameNodeId())
                        && a1.getParentFrameName().equals(a.getParentFrameName())) {
                    // System.out.println("--- found matching access object ---");
                    result = true;
                }
        }
        return result;
    }

    /**
     * Removes the last <number> of entries from this FrameHistory.
     *
     * @param number Number of entries to remove
     */
    void removeLastEntries(int number) {
        int counter;

        for (counter = 1; counter <= number; counter++) {
            if (!accessList.isEmpty()) {
                accessList.remove(accessList.size() - 1);
            }
        }
        if (accessList.size() - 1 > position)
           position = accessList.size() - 1;
    }

    /**
     * Removes the first <number> of entries from this FrameHistory.
     *
     * @param number Number of entries to remove
     */
    void removeFirstEntries(int number) {
        int counter;

        for (counter = 1; counter <= number; counter++) {
            if (!accessList.isEmpty()) {
                accessList.remove(0);
                position--;
            }
        }
    }


    /**
     * Get lastAction
     *
     * @return bit Array that holds reason for last new page
     */
    public int getLastAction() {
        return this.lastAction;
    }

    /**
     * Set lastAction
     *
     * @param lastAction Bit array that holds reason for last page change
     */
    public void setLastAction(int lastAction) {
        this.lastAction = lastAction;
    }

    /**
     * Get lastLinkType
     * @return bit Array that holds reason for last new page
     */
    public int getLastLinkType() {
        return this.lastLinkType;
    }
    
    /**
     * Set lastLinkType
     * @param lastLinkType Bit array that holds type of last clicked link...
     */
    public void setLastLinkType(int lastLinkType) {
        this.lastLinkType = lastLinkType;
    }
    
    /**
     * Get getLastReferrer
     * @return the NodeId of the last refferer
     */
    public String getLastReferrer() { return this.lastReferrer; }

    /**
     * Set setLastReferrer
     * @param lastAction Bit array that holds reason for last page change
     */
    public void setLastReferrer(String nodeId) { this.lastReferrer = nodeId; }

    /**
     * Get getLastLinkAnchor
     * @return the Text of the link anchor
     */
    public String getLastLinkAnchor() { return this.lastLinkAnchor; }

    /**
     * Set setLastReferrer
     * @param LinkAnchor text of last link
     */
    public void setLastLinkAnchor(String lastLinkAnchor) { this.lastLinkAnchor = lastLinkAnchor; }

    /**
     * Get LastLinkTitle
     * @return the title of last link
     */
    public String getLastLinkTitle() { return this.lastLinkTitle; }

    /**
     * Set setLastLinkTitle
     * @param title of last link
     */
    public void setLastLinkTitle(String lastLinkTitle) { this.lastLinkTitle = lastLinkTitle; }

    /**
     * Get getWindowSize
     * @return the last size of window...
     */
    public String getLastWindowSize() { return this.lastWindowSize; }

    /**
     * Set setLast Window Size
     * @param size of window at last click
     */
    public void setLastWindowSize(String lastWindowSize) { this.lastWindowSize = lastWindowSize; }

    /**
     * Get getLast Link Position
     * @return the position of the last click (on a link)
     */
    public String getLastLinkPos() { return this.lastLinkPos; }

    /**
     * Set setLastLinkPos
     * @param position of click on page (inlcuding the scrolling!)
     */
    public void setLastLinkPos(String lastLinkPos) { this.lastLinkPos = lastLinkPos; }


    /**
     * Get length of history
     *
     * @return length of history
     */
    int getHistoryLength() {
        return accessList.size();
    }


    /**
     * Set position in history
     *
     * @param position Position in history
     */
    public void setPosition(int position) {
        if (position <= accessList.size())
            this.position = position - 1;
    }

    /**
     * Get position in history
     *
     * @return position in history
     */
    public int getPosition() {
        return position + 1;
    }

    /**
     * Get last access event
     *
     * @return Access event
     */
    public Access getLastEvent() {
        if ((position < accessList.size()) && (accessList.size() > 0)) {
            return (Access) accessList.get(position);
        } else {
            System.out.println("FrameHistory.getLastEvent(): value of variable position outside of list. position = " + (position + 1) + ". Item, " + accessList.size() + " Items in FrameHistory.");
            return null;
        }
    }

    /**
     * Get access event at position i
     * @param i position of event
     * @return Access event
     */
    public Access getEventAt(int i) {
        if ((i-1 < accessList.size()) && (accessList.size() > 0) && (i>0)) {
            return (Access) accessList.get(i-1);
        } else {
            System.out.println("FrameHistory.getEventAt(): value of variable position outside of list. position = " + (position + 1) + ". Item, " + accessList.size() + " Items in FrameHistory.");
            return null;
        }
    }


    /**
     * Replace last megTime and access event
     *
     * @param megTime
     * @param a
     */
    public void replaceLastEvent(Access a) {
        if (!accessList.isEmpty() && (position >= 0)
                && (position < accessList.size())) {
            accessList.set(position, a);
        }
    }

    /**
     * Replace last megTime and access event.
     * This method has an extra parameter frameName to identify
     * the Access object, that has to be replaced
     *
     * @param frameName  Identifies the frame
     * @param megTime
     * @param a          The Access Event
     */
    public void replaceLastEvent(String frameName, Access a) {
        if (!accessList.isEmpty() && (position >= 0)
                && (position < accessList.size())) {
            accessList.set(position, a);
        }
    }

    /**
     * Get position and matching Access Object a in the FrameHistory.
     *
     * @param a The Access object
     * @return The position in history of that access object
     */
    public int getPosition(Access a) {
        int pos = 0;
        Access a1;

        for (int counter = 0; counter < accessList.size(); counter++) {
            a1 = (Access) accessList.get(counter);
            if (a1.getUserId().equals(a.getUserId())
                    && a1.getNodeId().equals(a.getNodeId())
                    && a1.getFrameName().equals(a.getFrameName())
                    && a1.getParentFrameNodeId().equals(a.getParentFrameNodeId())
                    && a1.getParentFrameName().equals(a.getParentFrameName())) {
                pos = counter + 1 ;
            }
        }
        return pos;
    }

    /**
     * Show the contents of the FrameHistory.
     *
     * @return distance of position and a in history
     */
    public void showFrameContents() {
        int counter;

        for (counter = 0; counter < accessList.size(); counter++) {
            System.out.println(counter + " Access obj. with FrameName = " + ((Access) accessList.get(counter)).getFrameName());
        }
    }

   
}
