/*
* Copyright (C) 2016 Naman Dwivedi
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software 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 General Public License for more details.
*/
package com.naman14.algovisualizer;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.naman14.algovisualizer.algorithm.Algorithm;
import com.naman14.algovisualizer.algorithm.graph.BellmanFordAlgorithm;
import com.naman14.algovisualizer.algorithm.graph.DijkstraAgorithm;
import com.naman14.algovisualizer.algorithm.graph.GraphTraversalAlgorithm;
import com.naman14.algovisualizer.algorithm.list.LinkedList;
import com.naman14.algovisualizer.algorithm.list.Stack;
import com.naman14.algovisualizer.algorithm.search.BinarySearch;
import com.naman14.algovisualizer.algorithm.search.LinearSearch;
import com.naman14.algovisualizer.algorithm.sorting.BubbleSort;
import com.naman14.algovisualizer.algorithm.sorting.InsertionSort;
import com.naman14.algovisualizer.algorithm.sorting.SelectionSort;
import com.naman14.algovisualizer.algorithm.tree.bst.BSTAlgorithm;
import com.naman14.algovisualizer.visualizer.AlgorithmVisualizer;
import com.naman14.algovisualizer.visualizer.ArrayVisualizer;
import com.naman14.algovisualizer.visualizer.BSTVisualizer;
import com.naman14.algovisualizer.visualizer.BinarySearchVisualizer;
import com.naman14.algovisualizer.visualizer.LinkedListControls;
import com.naman14.algovisualizer.visualizer.LinkedListVisualizer;
import com.naman14.algovisualizer.visualizer.SortingVisualizer;
import com.naman14.algovisualizer.visualizer.StackControls;
import com.naman14.algovisualizer.visualizer.StackVisualizer;
import com.naman14.algovisualizer.visualizer.graph.DirectedGraphVisualizer;
import com.naman14.algovisualizer.visualizer.graph.WeightedGraphVisualizer;
import com.naman14.algovisualizer.visualizer.graph.WeightedGraphVisualizer2;
import com.roughike.bottombar.BottomBar;
import com.roughike.bottombar.BottomBarTab;
import com.roughike.bottombar.OnTabClickListener;
import java.util.ArrayList;
import java.util.List;
public class VisualAlgoFragment extends Fragment {
FloatingActionButton fab;
BottomBar bottomBar;
AppBarLayout appBarLayout;
LogFragment logFragment;
CodeFragment codeFragment;
AlgoDescriptionFragment algoFragment;
ViewPager viewPager;
Algorithm algorithm;
String startCommand = Algorithm.COMMAND_START_ALGORITHM;
public static VisualAlgoFragment newInstance(String algorithm) {
VisualAlgoFragment fragment = new VisualAlgoFragment();
Bundle bundle = new Bundle();
bundle.putString(Algorithm.KEY_ALGORITHM, algorithm);
fragment.setArguments(bundle);
return fragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_visual_algo, container, false);
appBarLayout = (AppBarLayout) rootView.findViewById(R.id.app_bar);
bottomBar = BottomBar.attachShy((CoordinatorLayout) rootView.findViewById(R.id.coordinator), savedInstanceState);
bottomBar.noNavBarGoodness();
bottomBar.noTabletGoodness();
fab = (FloatingActionButton) rootView.findViewById(R.id.fab);
viewPager = (ViewPager) rootView.findViewById(R.id.viewPager);
bottomBar.setItems(
new BottomBarTab(R.drawable.ic_wb_incandescent_white_24dp, "Details"),
new BottomBarTab(R.drawable.ic_short_text_white_24dp, "Execution"),
new BottomBarTab(R.drawable.ic_code_white_24dp, "Code")
);
bottomBar.setOnTabClickListener(new OnTabClickListener() {
@Override
public void onTabSelected(int position) {
viewPager.setCurrentItem(position);
if (position == 2) {
bottomBar.hide();
}
}
@Override
public void onTabReSelected(int position) {
}
});
logFragment = LogFragment.newInstance();
codeFragment = CodeFragment.newInstance(getArguments().getString(Algorithm.KEY_ALGORITHM));
algoFragment = AlgoDescriptionFragment.newInstance(getArguments().getString(Algorithm.KEY_ALGORITHM));
setupFragment(getArguments().getString(Algorithm.KEY_ALGORITHM));
return rootView;
}
public void setStartCommand(String startCommand) {
this.startCommand = startCommand;
}
public void setupFragment(String algorithmKey) {
viewPager.setOffscreenPageLimit(3);
bottomBar.selectTabAtPosition(0, false);
setupViewPager(viewPager);
codeFragment.setCode(algorithmKey);
algoFragment.setCodeDesc(algorithmKey);
assert algorithmKey != null;
final AlgorithmVisualizer visualizer;
appBarLayout.removeAllViewsInLayout();
View toolbar = LayoutInflater.from(getActivity()).inflate(R.layout.toolbar, appBarLayout, false);
appBarLayout.addView(toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar((Toolbar) toolbar);
ActionBar ab = ((AppCompatActivity) getActivity()).getSupportActionBar();
assert ab != null;
ab.setTitle("");
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeAsUpIndicator(R.drawable.ic_menu_black_24dp);
fab.setVisibility(View.VISIBLE);
switch (algorithmKey) {
case Algorithm.BINARY_SEARCH:
visualizer = new BinarySearchVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new BinarySearch((BinarySearchVisualizer) visualizer, getActivity(), logFragment);
((BinarySearch) algorithm).setData(DataUtils.createArray(15, true));
break;
case Algorithm.LINEAR_SEARCH:
visualizer = new BinarySearchVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new LinearSearch((BinarySearchVisualizer) visualizer, getActivity(), logFragment);
((LinearSearch) algorithm).setData(DataUtils.createArray(15, false));
break;
case Algorithm.BUBBLE_SORT:
visualizer = new SortingVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new BubbleSort((SortingVisualizer) visualizer, getActivity(), logFragment);
((BubbleSort) algorithm).setData(DataUtils.createRandomArray(15));
break;
case Algorithm.INSERTION_SORT:
visualizer = new SortingVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new InsertionSort((SortingVisualizer) visualizer, getActivity(), logFragment);
((InsertionSort) algorithm).setData(DataUtils.createRandomArray(15));
break;
case Algorithm.SELECTION_SORT:
visualizer = new SortingVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new SelectionSort((SortingVisualizer) visualizer, getActivity(), logFragment);
((SelectionSort) algorithm).setData(DataUtils.createRandomArray(15));
break;
case Algorithm.BST_SEARCH:
visualizer = new BSTVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new BSTAlgorithm((BSTVisualizer) visualizer, getActivity(), logFragment);
((BSTAlgorithm) algorithm).setData(DataUtils.createBinaryTree());
break;
case Algorithm.BST_INSERT:
visualizer = new BSTVisualizer(getActivity(), 280);
ArrayVisualizer arrayVisualizer = new ArrayVisualizer(getActivity());
appBarLayout.addView(visualizer);
appBarLayout.addView(arrayVisualizer);
algorithm = new BSTAlgorithm((BSTVisualizer) visualizer, getActivity(), logFragment);
((BSTAlgorithm) algorithm).setArrayVisualizer(arrayVisualizer);
((BSTAlgorithm) algorithm).setData(DataUtils.createBinaryTree());
break;
case Algorithm.LINKED_LIST:
visualizer = new LinkedListVisualizer(getActivity());
LinkedListControls controls = new LinkedListControls(getActivity(), bottomBar, fab);
appBarLayout.addView(visualizer);
appBarLayout.addView(controls);
algorithm = new LinkedList((LinkedListVisualizer) visualizer, getActivity(), logFragment);
((LinkedList) algorithm).setData(DataUtils.createLinkedList());
controls.setLinkedList((LinkedList) algorithm);
break;
case Algorithm.STACK:
visualizer = new StackVisualizer(getActivity());
StackControls stackcontrols = new StackControls(getActivity(), bottomBar, fab);
appBarLayout.addView(visualizer);
appBarLayout.addView(stackcontrols);
algorithm = new Stack(5, (StackVisualizer) visualizer, getActivity(), logFragment);
((Stack) algorithm).setData(DataUtils.createStack());
stackcontrols.setStack((Stack) algorithm);
fab.setVisibility(View.GONE);
break;
case Algorithm.BFS:
case Algorithm.DFS:
visualizer = new DirectedGraphVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new GraphTraversalAlgorithm((DirectedGraphVisualizer) visualizer, getActivity(), logFragment);
((GraphTraversalAlgorithm) algorithm).setData(DataUtils.createDirectedGraph());
break;
case Algorithm.DIJKSTRA:
visualizer = new WeightedGraphVisualizer2(getActivity());
appBarLayout.addView(visualizer);
algorithm = new DijkstraAgorithm((WeightedGraphVisualizer2) visualizer, getActivity(), logFragment);
((DijkstraAgorithm) algorithm).setData(DataUtils.createWeightedGraph2(5));
break;
case Algorithm.BELLMAN_FORD:
visualizer = new WeightedGraphVisualizer(getActivity());
appBarLayout.addView(visualizer);
algorithm = new BellmanFordAlgorithm((WeightedGraphVisualizer) visualizer, getActivity(), logFragment);
((BellmanFordAlgorithm) algorithm).setData(DataUtils.createWeightedGraph(5));
break;
default:
visualizer = null;
}
algorithm.setStarted(false);
fab.setImageResource(R.drawable.ic_play_arrow_white_24dp);
logFragment.clearLog();
algorithm.setCompletionListener(new AlgoCompletionListener() {
@Override
public void onAlgoCompleted() {
fab.setImageResource(R.drawable.ic_settings_backup_restore_white_24dp);
if (visualizer != null)
visualizer.onCompleted();
}
});
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!algorithm.isStarted()) {
algorithm.sendMessage(startCommand);
fab.setImageResource(R.drawable.ic_pause_white_24dp);
logFragment.clearLog();
bottomBar.selectTabAtPosition(1, true);//move to log fragment
} else {
if (algorithm.isPaused()) {
algorithm.setPaused(false);
fab.setImageResource(R.drawable.ic_pause_white_24dp);
} else {
algorithm.setPaused(true);
fab.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
}
}
});
View shadow = LayoutInflater.from(getActivity()).inflate(R.layout.shadow, appBarLayout, false);
appBarLayout.addView(shadow);
}
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getChildFragmentManager());
adapter.addFragment(algoFragment, "Algo");
adapter.addFragment(logFragment, "Log");
adapter.addFragment(codeFragment, "Code");
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
bottomBar.selectTabAtPosition(position, false);
bottomBar.hide();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
private Adapter(FragmentManager fm) {
super(fm);
}
private void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
bottomBar.onSaveInstanceState(outState);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
}