<%@ page import="ro.emid.common.types.User" %>
<%@ page import="ro.emid.common.constants.UserConstants" %>
<%@ page import="java.util.*" %>
<%@ page import="ro.emid.common.constants.AppConstants" %>
<%@ page import="ro.emid.common.utils.ObjectUtils" %>

<%@ include file="../../layout/declaratii.jsp"%>
<%

    final int HISTORY_MAX_VISITS = 5;
    final int SESSION_MAX_IDLE = 5 * 60 * 1000;
    final int CLEAR_TIMER_PERIOD = 10*1000;

    class Visit{
        private final Date date;
        private final String url;

        public Visit(final Date date, final String url) {
            this.date = date;
            this.url = url;
        }
    }

    class UserHistory{
        private final String user;
        private final List visits = new LinkedList();


        public UserHistory(final String user) {
            this.user = user;
        }

        public void addNewVisit(final Date date, final String url){
            if( visits.size() > HISTORY_MAX_VISITS){
                visits.remove(0);
            }
            visits.add( new Visit(date, url));
        }

        public Visit getLastVisit(){
            if( visits.size() > 0){
                return (Visit) visits.get( visits.size() - 1);
            }
            return null;
        }

        public boolean areNewVisits(final long lastCheckTime){
            for (int i = 0; i < visits.size(); i++) {
                final Visit visit = (Visit) visits.get(i);
                if( visit.date.getTime() - lastCheckTime > 0){
                    return true;
                }
            }
            return false;
        }

        public void print(){
            System.out.println("[EMID] User: " + user);
            for (int i = 0; i < visits.size(); i++) {
                final Visit visit = (Visit) visits.get(i);
                System.out.println("[EMID] " + AppConstants.formatx(visit.date) + ' ' + visit.url);
            }
        }
    }

    class TrackData{
        HashMap map = new HashMap();

        public TrackData(){
//            new Timer().schedule(new TimerTask(){
//                public void run() {
//                    clear();
//                }
//            }, CLEAR_TIMER_PERIOD);
        }

        public synchronized void addNewVisit(final String username, final String url){
            clear();
            
            UserHistory userHistory = (UserHistory) map.get( username);
            if( userHistory == null){
                userHistory = new UserHistory( username);
            }

            userHistory.addNewVisit(new Date(System.currentTimeMillis()), url);
            map.put( username, userHistory);
        }

        private void clear(){
            final Set keys = map.keySet();
            for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
                final String username = (String) iterator.next();
                final UserHistory userHistory = (UserHistory) map.get( username);

                final Visit lastVisit = userHistory.getLastVisit();
                if( sessionExpired( lastVisit.date)){
                    map.remove( username);
                }
            }
        }

        private boolean sessionExpired(final Date lastVisitTime){
            return ( System.currentTimeMillis() - lastVisitTime.getTime() > SESSION_MAX_IDLE );
        }

        public boolean areNewVisits(final long lastCheckTime, final long countUsersShown){
            clear();
            
            if( countUsersShown != map.size()) return true;

            final Set keys = map.keySet();
            for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
                final String username = (String) iterator.next();
                final UserHistory userHistory = (UserHistory) map.get( username);
                if( userHistory.areNewVisits( lastCheckTime)) return true;
            }
            return false;
        }

        public long userCount(){
            return map.size();
        }

        public void print(){
            final Set keys = map.keySet();
            for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
                final String username = (String) iterator.next();
                final UserHistory userHistory = (UserHistory) map.get( username);
                userHistory.print();
            }
        }
    }
    //}Workers
    

    // UI
    TrackData td  = null;
    try {
        td = (TrackData) application.getAttribute("_trackData_");
    } catch (Exception e) {
    }

    if( td == null) {
        td = new TrackData();
        application.setAttribute( "_trackData_", td);
    }

    final String action = request.getParameter("a");

    if( "add".equals( action)){
        final String referer = request.getHeader("referer");
        System.out.println("[EMID] referer = " + referer);

        if( user != null && referer != null && referer.indexOf("visits") == -1){
            td.addNewVisit( user.getUsername(), referer);
            td.print();
        }
    }else if("show".equals( action))  { %>

        <style type="text/css">
            .userDiv{
                border-color:#66cc00;
                border-width:1px;
                border-style:solid;
                margin:2px;
                background-color:#ffffcc;
                font-size:14px;
            }

            .userHeader{
                background-color:#dffca3;
                padding:2px;
                padding-left:5px;
            }

            .userVisits{
                padding-left:18px;
                border-top-color:#66cc00;
                border-top-width:1px;
                border-top-style:solid;
            }
        </style>

        <div style="margin:10px">
            <% final Collection historries = td.map.values(); %>
            <% for (Iterator iterator = historries.iterator(); iterator.hasNext();) {
                final UserHistory userHistory = (UserHistory) iterator.next();

                final Visit lastVisit = userHistory.getLastVisit();
            %>
                <div class="userDiv">
                    <div class="userHeader">
                        <span id="plusForUser<%=userHistory.user%>"></span>
                        <span style="width:100px"><%=userHistory.user%></span> | <%=AppConstants.formatx(lastVisit.date)%> | <%=lastVisit.url%>
                    </div>
                    <div id="vizite<%=userHistory.user%>" class="userVisits"  >
                        <%
                            final List visits = userHistory.visits;
                            for (int i = visits.size()-2; i >= 0; i--) {
                                final Visit visit = (Visit) visits.get(i); %>
                                <span style="width:100px">&nbsp;</span> | <%=AppConstants.formatx(visit.date)%> | <%=visit.url%><br>
                        <%}%>
                    </div>

                     <script type="text/javascript">
                        var plus<%=userHistory.user%> = new Plus( "plusForUser<%=userHistory.user%>", "vizite<%=userHistory.user%>");
                    </script>
                </div>
            <%} %>
        </div>


        <script type="text/javascript">
            var PERIOD = 10*1000;
            var lastVisitTime = <%=System.currentTimeMillis()%>;
            var userCount = <%=td.userCount()%>;

            function checkForNewVisits(){
                var params = "&a=checkForNewVisits&lastCheckTime="+lastVisitTime + "&countUsers="+userCount;
                new Ajax.Request('<%=AppConstants.APP_NAME%>?action=visits',
                        {
                            method: 'post',
                            parameters: params,
                            onComplete: function (originalRequest){
                                var response = getResponseMesg( originalRequest.responseText);
                                if( response != null && response.toLowerCase().trim() == "true"){

                                    window.location.reload();

                                }else{
                                    lastVisitTime += PERIOD;
                                    startTimeout();
                                }
                            }
                        });
            }

            function startTimeout(){
                setTimeout("checkForNewVisits()", PERIOD);
            }

            startTimeout();
        </script>
    <%}else if( "checkForNewVisits".equals(action)){
        final long lastCheckTime = ObjectUtils.getLongValue(request.getParameter("lastCheckTime"));
        final long countUsersShown = ObjectUtils.getLongValue(request.getParameter("countUsers"));%>
        <respmesg><%=td.areNewVisits( lastCheckTime, countUsersShown)%></respmesg>
    <%}%>
