// Path: library/src/main/java/flownavigation/path/Path.java
// public abstract class Path {
// 
//     static final Path ROOT = new Path() {
//     };
// 
//     public static PathContextFactory contextFactory() {
//         return new ContextFactory();
//     }
// 
//     public static PathContextFactory contextFactory(PathContextFactory delegate) {
//         return new ContextFactory(delegate);
//     }
// 
//     private static final class LocalPathWrapper extends ContextWrapper {
//         static final String LOCAL_WRAPPER_SERVICE = "flow_local_screen_context_wrapper";
//         private LayoutInflater inflater;
// 
//         final Object localScreen;
// 
//         LocalPathWrapper(Context base, Object localScreen) {
//             super(base);
//             this.localScreen = localScreen;
//         }
// 
//         @Override
//         public Object getSystemService(String name) {
//             if (LOCAL_WRAPPER_SERVICE.equals(name)) {
//                 return this;
//             }
//             if (LAYOUT_INFLATER_SERVICE.equals(name)) {
//                 if (inflater == null) {
//                     inflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
//                 }
//                 return inflater;
//             }
//             return super.getSystemService(name);
//         }
//     }
// 
//     private static final class ContextFactory implements PathContextFactory {
//         // May be null.
//         private final PathContextFactory delegate;
// 
//         public ContextFactory() {
//             delegate = null;
//         }
// 
//         public ContextFactory(PathContextFactory delegate) {
//             this.delegate = delegate;
//         }
// 
//         @Override
//         public Context setUpContext(Path path, Context parentContext) {
//             if (delegate != null) {
//                 parentContext = delegate.setUpContext(path, parentContext);
//             }
//             return new LocalPathWrapper(parentContext, path);
//         }
// 
//         @Override
//         public void tearDownContext(Context context) {
//             if (delegate != null) {
//                 delegate.tearDownContext(context);
//             }
//         }
//     }
// }


import android.content.Context;
import android.util.Log;
import flownavigation.path.Path;
import mortar.MortarScope;
package flownavigation.common.mortar;



/**
 * @author Lukasz Piliszczuk - lukasz.pili@gmail.com
 */
public abstract class BasicScreenScoper implements ScreenScoper {

    public MortarScope getScreenScope(Context context, String name, Path path) {
        MortarScope parentScope = MortarScope.getScope(context);
        Log.d(getClass().getCanonicalName(), "ScreenScoper - Screen scoper with parent " + parentScope.getName());

        MortarScope childScope = parentScope.findChild(name);
        if (childScope != null) {
            Log.d(getClass().getCanonicalName(), "ScreenScoper - Screen scoper returns existing scope " + name);
            return childScope;
        }

        MortarScope.Builder builder = parentScope.buildChild();
        configureMortarScope(context, name, path, parentScope, builder);

        Log.d(getClass().getCanonicalName(), "ScreenScoper - Screen scoper builds and returns new scope " + name);
        return builder.build(name);
    }

// Path: library/src/main/java/flownavigation/path/Path.java
// public abstract class Path {
// 
//     static final Path ROOT = new Path() {
//     };
// 
//     public static PathContextFactory contextFactory() {
//         return new ContextFactory();
//     }
// 
//     public static PathContextFactory contextFactory(PathContextFactory delegate) {
//         return new ContextFactory(delegate);
//     }
// 
//     private static final class LocalPathWrapper extends ContextWrapper {
//         static final String LOCAL_WRAPPER_SERVICE = "flow_local_screen_context_wrapper";
//         private LayoutInflater inflater;
// 
//         final Object localScreen;
// 
//         LocalPathWrapper(Context base, Object localScreen) {
//             super(base);
//             this.localScreen = localScreen;
//         }
// 
//         @Override
//         public Object getSystemService(String name) {
//             if (LOCAL_WRAPPER_SERVICE.equals(name)) {
//                 return this;
//             }
//             if (LAYOUT_INFLATER_SERVICE.equals(name)) {
//                 if (inflater == null) {
//                     inflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
//                 }
//                 return inflater;
//             }
//             return super.getSystemService(name);
//         }
//     }
// 
//     private static final class ContextFactory implements PathContextFactory {
//         // May be null.
//         private final PathContextFactory delegate;
// 
//         public ContextFactory() {
//             delegate = null;
//         }
// 
//         public ContextFactory(PathContextFactory delegate) {
//             this.delegate = delegate;
//         }
// 
//         @Override
//         public Context setUpContext(Path path, Context parentContext) {
//             if (delegate != null) {
//                 parentContext = delegate.setUpContext(path, parentContext);
//             }
//             return new LocalPathWrapper(parentContext, path);
//         }
// 
//         @Override
//         public void tearDownContext(Context context) {
//             if (delegate != null) {
//                 delegate.tearDownContext(context);
//             }
//         }
//     }
// }


// Path: mortar-common/src/main/java/flownavigation/common/mortar/BasicScreenScoper.java
import android.content.Context;
import android.util.Log;
import flownavigation.path.Path;
import mortar.MortarScope;

package flownavigation.common.mortar;



/**
 * @author Lukasz Piliszczuk - lukasz.pili@gmail.com
 */
public abstract class BasicScreenScoper implements ScreenScoper {

    public MortarScope getScreenScope(Context context, String name, Path path) {
        MortarScope parentScope = MortarScope.getScope(context);
        Log.d(getClass().getCanonicalName(), "ScreenScoper - Screen scoper with parent " + parentScope.getName());

        MortarScope childScope = parentScope.findChild(name);
        if (childScope != null) {
            Log.d(getClass().getCanonicalName(), "ScreenScoper - Screen scoper returns existing scope " + name);
            return childScope;
        }

        MortarScope.Builder builder = parentScope.buildChild();
        configureMortarScope(context, name, path, parentScope, builder);

        Log.d(getClass().getCanonicalName(), "ScreenScoper - Screen scoper builds and returns new scope " + name);
        return builder.build(name);
    }

    protected abstract void configureMortarScope(Context context, String name, Path path, MortarScope parentScope, MortarScope.Builder mortarScopeBuilder);