package treehou.se.habit.ui.sitemaps;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.google.gson.Gson;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import javax.inject.Inject;
import io.realm.Realm;
import se.treehou.ng.ohcommunicator.connector.GsonHelper;
import se.treehou.ng.ohcommunicator.connector.models.OHLinkedPage;
import se.treehou.ng.ohcommunicator.connector.models.OHServer;
import se.treehou.ng.ohcommunicator.connector.models.OHSitemap;
import se.treehou.ng.ohcommunicator.services.IServerHandler;
import treehou.se.habit.HabitApplication;
import treehou.se.habit.R;
import treehou.se.habit.core.db.model.ServerDB;
import treehou.se.habit.ui.homescreen.VoiceService;
import treehou.se.habit.util.ConnectionFactory;
import treehou.se.habit.util.RxUtil;
public class SitemapFragment extends Fragment {
private static final String TAG = "SitemapFragment";
private static final String ARG_SITEMAP = "ARG_SITEMAP";
private static final String ARG_SERVER = "ARG_SERVER";
@Inject Gson gson;
@Inject ConnectionFactory connectionFactory;
private Realm realm;
private ServerDB server;
private OHSitemap sitemap;
/**
* Creates a new instance of fragment showing sitemap.
*
* @param server the server to use to open sitemap.
* @param sitemap the sitemap to load.
* @return Fragment displaying sitemap.
*/
public static SitemapFragment newInstance(OHServer server, OHSitemap sitemap){
ServerDB serverDB = Realm.getDefaultInstance()
.where(ServerDB.class)
.equalTo("name", server.getName())
.findFirst();
return newInstance(serverDB, sitemap);
}
/**
* Creates a new instance of fragment showing sitemap.,
*
* @param serverDB the server to use to open sitemap.
* @param sitemap the sitemap to load.
* @return Fragment displaying sitemap.
*/
public static SitemapFragment newInstance(ServerDB serverDB, OHSitemap sitemap){
SitemapFragment fragment = new SitemapFragment();
Bundle args = new Bundle();
args.putString(ARG_SITEMAP, GsonHelper.createGsonBuilder().toJson(sitemap));
args.putLong(ARG_SERVER, serverDB.getId());
fragment.setArguments(args);
return fragment;
}
public SitemapFragment() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getComponent().inject(this);
realm = Realm.getDefaultInstance();
long serverId = getArguments().getLong(ARG_SERVER);
server = ServerDB.load(realm, serverId);
String jSitemap = getArguments().getString(ARG_SITEMAP);
sitemap = gson.fromJson(jSitemap, OHSitemap.class);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setupActionbar();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_sitemap, container, false);
setHasOptionsMenu(true);
return rootView;
}
@Override
public void onResume() {
super.onResume();
if(!hasPage()) {
final IServerHandler serverHandler = connectionFactory.createServerHandler(sitemap.getServer(), getActivity());
serverHandler.requestPageRx(sitemap.getHomepage())
.compose(RxUtil.newToMainSchedulers())
.subscribe(linkedPage -> {
Log.d(TAG, "Received page " + linkedPage);
addPage(linkedPage);
}, e -> {
Log.d(TAG, "Received page failed", e);
});
}
EventBus.getDefault().register(this);
}
@Override
public void onPause() {
EventBus.getDefault().unregister(this);
super.onPause();
}
protected HabitApplication.ApplicationComponent getComponent() {
return ((HabitApplication) getActivity().getApplication()).component();
}
/**
* Setup actionbar using
*/
private void setupActionbar(){
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if(actionBar != null) actionBar.setTitle(sitemap.getLabel());
}
/**
* Check if a page is loaded.
* @return true if page loaded, else false.
*/
private boolean hasPage(){
return getChildFragmentManager().getBackStackEntryCount() > 0;
}
/**
* Add and move to page in view pager.
*
* @param page the page to add to pager
*/
public void addPage(OHLinkedPage page) {
FragmentManager fragmentManager = getChildFragmentManager();
if(fragmentManager == null) return;
Log.d(TAG, "Add page " + page.getLink());
getChildFragmentManager().beginTransaction()
.replace(R.id.pgr_sitemap, PageFragment.newInstance(server, page))
.addToBackStack(null)
.commit();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.sitemap, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_voice_command:
openVoiceCommand(server);
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Start voice command listener.
*
* @param server server to send command to.
*/
public void openVoiceCommand(ServerDB server){
Intent callbackIntent = VoiceService.createVoiceCommand(getActivity(), server);
PendingIntent openhabPendingIntent = PendingIntent.getService(getActivity(), 9, callbackIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
// Specify the calling package to identify your application
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, VoiceService.class.getPackage().getName());
// Display an hint to the user about what he should say.
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.voice_command_title));
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, openhabPendingIntent);
startActivity(intent);
}
/**
* Pop backstack
* @return true if handled by fragment, else false.
*/
public boolean popStack(){
FragmentManager fragmentManager = getChildFragmentManager();
int backStackEntryCount = fragmentManager.getBackStackEntryCount();
if(backStackEntryCount > 0){
fragmentManager.popBackStackImmediate();
}
backStackEntryCount = fragmentManager.getBackStackEntryCount();
return backStackEntryCount >= 1;
}
/**
* User requested to move to new page.
*
* @param event
*/
@Subscribe
public void onEvent(OHLinkedPage event){
addPage(event);
}
@Override
public void onDestroy() {
super.onDestroy();
realm.close();
}
}