package lt.inventi.wicket.component.breadcrumb;

import static lt.inventi.wicket.component.breadcrumb.BreadcrumbPageParameters.getOptionalTrailId;

import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.Session;
import org.apache.wicket.application.IComponentInitializationListener;
import org.apache.wicket.application.IComponentInstantiationListener;
import org.apache.wicket.application.IComponentOnBeforeRenderListener;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.component.IRequestablePage;


public class BreadcrumbTrailExtendingListener implements IComponentOnBeforeRenderListener {
    /**
     * We cannot use {@link IComponentInitializationListener} or
     * {@link IComponentInstantiationListener} because navigation to the
     * breadcrumbs in the trail won't always create/initialize pages (in case
     * they're stateful and still in page store). We construct unique trail ids
     * based on the page's hashCode and a deserialized page's hashCode doesn't
     * have to match the hashCode of the serialized one, thus we cannot reliably
     * find the previous page trail without extending it on each render.
     * <p>
     * Possible improvement: store the newly created breadcrumb in the session's
     * metadata and use it in all further next page links. This way we can use
     * stable breadcrumb ids (page id + page class) and avoid creating new
     * breadcrumbs when the same page is rerendered (same page id + class but
     * different page object and thus hashCode).
     */

    private final IBreadcrumbPageFilter pageFilter;

    public BreadcrumbTrailExtendingListener(IBreadcrumbPageFilter pageFilter) {
        this.pageFilter = pageFilter;
    }

    @Override
    public void onBeforeRender(Component component) {
        if (component instanceof Page && pageFilter.shouldCreateBreadcrumbFor((IRequestablePage) component)) {
            Page p = (Page) component;
            Breadcrumb crumb = createBreadcrumbFrom(p);
            String maybeTrailId = getOptionalTrailId(p.getPageParameters());
            BreadcrumbTrailHistory.extendTrail(maybeTrailId, crumb);
            System.out.println("Session: " + Session.get().getSizeInBytes() + " b.");
        }
    }

    private static Breadcrumb createBreadcrumbFrom(Page p) {
        final IModel<String> titleModel;
        if (p instanceof IProvideTitle) {
            titleModel = ((IProvideTitle) p).getTitle();
        } else {
            titleModel = Model.of(((Component) p).getString("breadcrumb"));
        }
        return new Breadcrumb(p, titleModel);
    }

}

@@ -592,16 +592,73 @@
 lePage;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 %0A%0Apublic
@@ -1004,16 +1004,20 @@
 till in 
+the 
 page sto
@@ -1050,19 +1050,19 @@
 rail
- ids
 %0A     *
+ ids
  bas
@@ -1125,16 +1125,23 @@
 Code
+%0A     *
  doesn't
 %0A   
@@ -1136,23 +1136,16 @@
  doesn't
-%0A     *
  have to
@@ -1201,16 +1201,23 @@
 e cannot
+%0A     *
  reliabl
@@ -1217,23 +1217,16 @@
 reliably
-%0A     *
  find th
@@ -1275,16 +1275,23 @@
  on each
+%0A     *
  render.
@@ -1671,16 +1671,122 @@
 %0A     */
+%0A    private static final Logger logger = LoggerFactory.getLogger(BreadcrumbTrailExtendingListener.class);
 %0A%0A    pr
@@ -2066,12 +2066,28 @@
 Page
- && 
+) %7B%0A            if (
 page
@@ -2164,16 +2164,20 @@
         
+  
+  
 Page p =
@@ -2195,16 +2195,20 @@
 ponent;%0A
+    
         
@@ -2267,16 +2267,20 @@
         
+ 
+   
 String m
@@ -2340,32 +2340,36 @@
 ));%0A            
+    
 BreadcrumbTrailH
@@ -2409,16 +2409,17 @@
 crumb);%0A
+%0A
         
@@ -2426,81 +2426,485 @@
     
-System.out.println(%22Session: %22 + Session.get().getSizeInBytes() + %22 b.%22);
+    if (logger.isTraceEnabled()) %7B%0A                    logger.trace(%22Extended breadcrumb trail for trail %7B%7D with crumb %7B%7D%22, maybeTrailId, crumb);%0A                    logger.trace(%22Session size after extending trail: %22 + Session.get().getSizeInBytes() + %22 bytes%22);%0A                %7D%0A            %7D else %7B%0A                if (logger.isTraceEnabled()) %7B%0A                    logger.trace(%22Skipping breadcrumb trail extension for page: %22 + component);%0A                %7D%0A            %7D
 %0A   

Replace system out with proper logging