// 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: library/src/main/java/flownavigation/path/PathContainer.java
// public abstract class PathContainer {
// 
//     /**
//      * Provides information about the current or most recent Traversal handled by the container.
//      */
//     protected static final class TraversalState {
//         private Path fromPath;
//         private ViewState fromViewState;
//         private Path toPath;
//         private ViewState toViewState;
// 
//         public void setNextEntry(Path path, ViewState viewState) {
//             this.fromPath = this.toPath;
//             this.fromViewState = this.toViewState;
//             this.toPath = path;
//             this.toViewState = viewState;
//         }
// 
//         public Path fromPath() {
//             return fromPath;
//         }
// 
//         public Path toPath() {
//             return toPath;
//         }
// 
//         public void saveViewState(View view) {
//             fromViewState.save(view);
//         }
// 
//         public void restoreViewState(View view) {
//             toViewState.restore(view);
//         }
//     }
// 
//     private static final Map<Class, Integer> PATH_LAYOUT_CACHE = new LinkedHashMap<>();
// 
//     private final int tagKey;
// 
//     protected PathContainer(int tagKey) {
//         this.tagKey = tagKey;
//     }
// 
//     public final void executeTraversal(PathContainerView view, Flow.Traversal traversal,
//                                        final Flow.TraversalCallback callback) {
// 
//         final View oldChild = view.getCurrentChild();
// 
//         Path path = traversal.destination.top();
//         ViewState viewState = traversal.destination.currentViewState();
// 
//         Path oldPath;
//         ViewGroup containerView = view.getContainerView();
//         TraversalState traversalState = ensureTag(containerView);
// 
//         // See if we already have the direct child we want, and if so short circuit the traversal.
//         if (oldChild != null) {
//             oldPath = Preconditions.checkNotNull(traversalState.toPath, "Container view has child %s with no path", oldChild.toString());
//             if (oldPath.equals(path)) {
//                 callback.onTraversalCompleted();
//                 return;
//             }
//         }
// 
//         traversalState.setNextEntry(path, viewState);
//         performTraversal(containerView, traversalState, traversal.direction, callback);
//     }
// 
//     protected abstract void performTraversal(ViewGroup container, TraversalState traversalState,
//                                              Flow.Direction direction, Flow.TraversalCallback callback);
// 
//     private TraversalState ensureTag(ViewGroup container) {
//         TraversalState traversalState = (TraversalState) container.getTag(tagKey);
//         if (traversalState == null) {
//             traversalState = new TraversalState();
//             container.setTag(tagKey, traversalState);
//         }
//         return traversalState;
//     }
// }
// 
// Path: library/src/main/java/flownavigation/path/PathContainerView.java
// public interface PathContainerView extends Flow.Dispatcher {
//     ViewGroup getCurrentChild();
// 
//     ViewGroup getContainerView();
// 
//     Context getContext();
// 
//     void dispatch(Flow.Traversal traversal, Flow.TraversalCallback callback);
// }


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import flow.Flow;
import flownavigation.path.Path;
import flownavigation.path.PathContainer;
import flownavigation.path.PathContainerView;
/*
 * Copyright 2014 Square Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package flownavigation.common.flow;




/**
 * A FrameLayout that can show screens for a {@link Flow}.
 * <p/>
 * Copy past from flow-sample
 *
 * @author Lukasz Piliszczuk - lukasz.pili@gmail.com
 */
public class FramePathContainerView extends FrameLayout
        implements HandlesBack, PathContainerView {
// 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: library/src/main/java/flownavigation/path/PathContainer.java
// public abstract class PathContainer {
// 
//     /**
//      * Provides information about the current or most recent Traversal handled by the container.
//      */
//     protected static final class TraversalState {
//         private Path fromPath;
//         private ViewState fromViewState;
//         private Path toPath;
//         private ViewState toViewState;
// 
//         public void setNextEntry(Path path, ViewState viewState) {
//             this.fromPath = this.toPath;
//             this.fromViewState = this.toViewState;
//             this.toPath = path;
//             this.toViewState = viewState;
//         }
// 
//         public Path fromPath() {
//             return fromPath;
//         }
// 
//         public Path toPath() {
//             return toPath;
//         }
// 
//         public void saveViewState(View view) {
//             fromViewState.save(view);
//         }
// 
//         public void restoreViewState(View view) {
//             toViewState.restore(view);
//         }
//     }
// 
//     private static final Map<Class, Integer> PATH_LAYOUT_CACHE = new LinkedHashMap<>();
// 
//     private final int tagKey;
// 
//     protected PathContainer(int tagKey) {
//         this.tagKey = tagKey;
//     }
// 
//     public final void executeTraversal(PathContainerView view, Flow.Traversal traversal,
//                                        final Flow.TraversalCallback callback) {
// 
//         final View oldChild = view.getCurrentChild();
// 
//         Path path = traversal.destination.top();
//         ViewState viewState = traversal.destination.currentViewState();
// 
//         Path oldPath;
//         ViewGroup containerView = view.getContainerView();
//         TraversalState traversalState = ensureTag(containerView);
// 
//         // See if we already have the direct child we want, and if so short circuit the traversal.
//         if (oldChild != null) {
//             oldPath = Preconditions.checkNotNull(traversalState.toPath, "Container view has child %s with no path", oldChild.toString());
//             if (oldPath.equals(path)) {
//                 callback.onTraversalCompleted();
//                 return;
//             }
//         }
// 
//         traversalState.setNextEntry(path, viewState);
//         performTraversal(containerView, traversalState, traversal.direction, callback);
//     }
// 
//     protected abstract void performTraversal(ViewGroup container, TraversalState traversalState,
//                                              Flow.Direction direction, Flow.TraversalCallback callback);
// 
//     private TraversalState ensureTag(ViewGroup container) {
//         TraversalState traversalState = (TraversalState) container.getTag(tagKey);
//         if (traversalState == null) {
//             traversalState = new TraversalState();
//             container.setTag(tagKey, traversalState);
//         }
//         return traversalState;
//     }
// }
// 
// Path: library/src/main/java/flownavigation/path/PathContainerView.java
// public interface PathContainerView extends Flow.Dispatcher {
//     ViewGroup getCurrentChild();
// 
//     ViewGroup getContainerView();
// 
//     Context getContext();
// 
//     void dispatch(Flow.Traversal traversal, Flow.TraversalCallback callback);
// }


// Path: flow-common/src/main/java/flownavigation/common/flow/FramePathContainerView.java
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import flow.Flow;
import flownavigation.path.Path;
import flownavigation.path.PathContainer;
import flownavigation.path.PathContainerView;

/*
 * Copyright 2014 Square Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package flownavigation.common.flow;




/**
 * A FrameLayout that can show screens for a {@link Flow}.
 * <p/>
 * Copy past from flow-sample
 *
 * @author Lukasz Piliszczuk - lukasz.pili@gmail.com
 */
public class FramePathContainerView extends FrameLayout
        implements HandlesBack, PathContainerView {
    private final PathContainer container;