/**
 *
 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either 
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 **/
package lucee.runtime.listener;

import lucee.commons.lang.types.RefBoolean;
import lucee.commons.lang.types.RefBooleanImpl;
import lucee.runtime.PageContext;
import lucee.runtime.PageContextImpl;
import lucee.runtime.PageSource;
import lucee.runtime.config.Constants;
import lucee.runtime.exp.PageException;
import lucee.runtime.type.Array;

/**
 * this class is only used by the CFML dialect, so checking for the dialect is not necessary
 */
public final class MixedAppListener extends ModernAppListener {

	@Override
	public void onRequest(PageContext pc, PageSource requestedPage, RequestListener rl) throws PageException {
		RefBoolean isCFC=new RefBooleanImpl(false);
		
		PageSource appPS=//pc.isCFCRequest()?null:
			getApplicationPageSource(pc, requestedPage, mode, isCFC);
		
		if(isCFC.toBooleanValue())_onRequest(pc, requestedPage,appPS,rl);
		else ClassicAppListener._onRequest(pc, requestedPage,appPS,rl);
	}
	
	@Override
	public final String getType() {
		return "mixed";
	}
	
	private static PageSource getApplicationPageSource(PageContext pc,PageSource requestedPage, int mode, RefBoolean isCFC) {
		if(mode==ApplicationListener.MODE_CURRENT2ROOT)
			return getApplicationPageSourceCurrToRoot(pc, requestedPage, isCFC);
		if(mode==ApplicationListener.MODE_CURRENT_OR_ROOT)
			return getApplicationPageSourceCurrOrRoot(pc, requestedPage, isCFC);
		if(mode==ApplicationListener.MODE_CURRENT)
			return getApplicationPageSourceCurrent(requestedPage, isCFC);
		return getApplicationPageSourceRoot(pc, isCFC);
	}
	
	private static PageSource getApplicationPageSourceCurrent(PageSource requestedPage, RefBoolean isCFC) {
		PageSource res=requestedPage.getRealPage(Constants.CFML_APPLICATION_EVENT_HANDLER);
	    if(res.exists()) {
	    	isCFC.setValue(true);
	    	return res;
	    }
	    res=requestedPage.getRealPage(Constants.CFML_CLASSIC_APPLICATION_EVENT_HANDLER);
	    if(res.exists()) return res;
		return null;
	}
	
	private static PageSource getApplicationPageSourceCurrToRoot(PageContext pc,PageSource requestedPage, RefBoolean isCFC) {
	    PageSource res=requestedPage.getRealPage(Constants.CFML_APPLICATION_EVENT_HANDLER);
	    if(res.exists()) {
	    	isCFC.setValue(true);
	    	return res;
	    }
	    //res=requestedPage.getRealPage(Constants.APP_CFM);
	    //if(res.exists()) return res;
	    
	    Array arr=lucee.runtime.type.util.ListUtil.listToArrayRemoveEmpty(requestedPage.getRealpathWithVirtual(),"/");
		//Config config = pc.getConfig();
		String path;
		for(int i=arr.size()-1;i>0;i--) {
		    StringBuilder sb=new StringBuilder("/");
			for(int y=1;y<i;y++) {
			    sb.append((String)arr.get(y,""));
			    sb.append('/');
			}
			path=sb.toString();
			res = ((PageContextImpl)pc).getPageSourceExisting(path.concat(Constants.CFML_APPLICATION_EVENT_HANDLER));
			if(res!=null) {
				isCFC.setValue(true);
				return res;
			}
			res = ((PageContextImpl)pc).getPageSourceExisting(path.concat(Constants.CFML_CLASSIC_APPLICATION_EVENT_HANDLER));
			if(res!=null) return res;
		}
		return null;
	}
	
	private static PageSource getApplicationPageSourceCurrOrRoot(PageContext pc,PageSource requestedPage, RefBoolean isCFC) {
	    // current 
		PageSource res=requestedPage.getRealPage(Constants.CFML_APPLICATION_EVENT_HANDLER);
	    if(res.exists()) {
	    	isCFC.setValue(true);
	    	return res;
	    }
	    
	    // root
	    return getApplicationPageSourceRoot(pc, isCFC);
	}
	
	private static PageSource getApplicationPageSourceRoot(PageContext pc, RefBoolean isCFC) {
		PageSource ps = ((PageContextImpl)pc).getPageSourceExisting("/"+Constants.CFML_APPLICATION_EVENT_HANDLER);
		if(ps!=null) {
			isCFC.setValue(true);
	    	return ps;
		}
		ps = ((PageContextImpl)pc).getPageSourceExisting("/"+Constants.CFML_CLASSIC_APPLICATION_EVENT_HANDLER);
		if(ps!=null) return ps;
		return null;
	}
}
@@ -1740,24 +1740,26 @@
 ixed%22;%0A%09%7D%0A%09%0A
+%09%0A
 %09private sta
@@ -1869,16 +1869,16 @@
 sCFC) %7B%0A
-
 %09%09if(mod
@@ -2813,20 +2813,17 @@
 CFC) %7B%0A%09
-    
+%09
 PageSour
@@ -2833,235 +2833,78 @@
 res=
-requestedPage.getRealPage(Constants.CFML_APPLICATION_EVENT_HANDLER);%0A%09    if(res.exists()) %7B%0A%09    %09isCFC.setValue(true);%0A%09    %09return res;%0A%09    %7D%0A%09    //res=requestedPage.getRealPage(Constants.APP_CFM
+getApplicationPageSourceCurrent(requestedPage, isCFC
 );%0A%09
-    //if(res.exists()) 
+%09if(res!=null)
 retu
@@ -2913,24 +2913,30 @@
  res;%0A%09    %0A
+%09    %0A
 %09    Array a
@@ -3797,135 +3797,78 @@
 res=
-requestedPage.getRealPage(Constants.CFML_APPLICATION_EVENT_HANDLER);%0A%09    if(res.exists()) %7B%0A%09    %09isCFC.setValue(true);%0A%09    %09
+getApplicationPageSourceCurrent(requestedPage, isCFC);%0A%09%09if(res!=null)
 retu
@@ -3871,31 +3871,24 @@
 return res;%0A
-%09    %7D%0A
 %09    %0A%09    /

remove redundant code