/*
* Copyright 2015. Appsi Mobile
*
* 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 com.appsimobile.appsii.hotspotmanager;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.LoaderManager;
import android.content.AsyncQueryHandler;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Loader;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.appsimobile.appsii.ActivityUtils;
import com.appsimobile.appsii.GotItDismissListener;
import com.appsimobile.appsii.HotspotItem;
import com.appsimobile.appsii.R;
import com.appsimobile.appsii.dagger.AppInjector;
import com.appsimobile.appsii.module.home.provider.HomeContract;
import java.util.ArrayList;
import javax.inject.Inject;
/**
* The main view of this feature. This shows a list of the hot-spots and
* handles the actions performed on it. It also allows adding new
* hot-spots.
* <p/>
* Created by Nick Martens on 8/16/13.
*/
public class ManageHotspotsActivity extends AppCompatActivity
implements HotspotActionListener,
LoaderManager.LoaderCallbacks<ArrayList<HotspotItem>> {
/**
* The adapter showing all of the hotspots
*/
HotspotAdapter mHotspotAdapter;
/**
* A handler to perform the updates with
*/
AsyncQueryHandlerImpl mAsyncQueryHandler;
@Inject
SharedPreferences mSharedPreferences;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppInjector.inject(this);
ActivityUtils.setContentViewWithFab(this, R.layout.activity_manage_hotspots);
View addPanelButton = ActivityUtils.setupFab(this, R.id.add_panel_button);
ActivityUtils.setupToolbar(this, R.id.toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mHotspotAdapter = new HotspotAdapter(this, mSharedPreferences);
mRecyclerView = (RecyclerView) findViewById(R.id.list);
mRecyclerView.setAdapter(mHotspotAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAsyncQueryHandler = new AsyncQueryHandlerImpl(this);
addPanelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onAddClicked();
}
});
getLoaderManager().initLoader(0, null, this);
}
/**
* Called when the add action is performed
*/
void onAddClicked() {
mAsyncQueryHandler.addNewHotspot();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public void performMainAction(HotspotItem configuration) {
onItemClicked(configuration);
}
void onItemClicked(HotspotItem configuration) {
String hotspotName = configuration.mName;
long id = configuration.mId;
long defaultPageId = configuration.mDefaultPageId;
HotspotSettingsFragment fragment = HotspotSettingsFragment.
createEditInstance(id, hotspotName, configuration.mDefaultPageId);
fragment.show(getFragmentManager(), "edit_hotspot");
}
@Override
public void performMoveHotspotAction(HotspotItem configuration) {
// Create an instance of the move-fragment and add it.
Fragment moveFragment = MoveHotspotFragment.createInstance(
configuration.mId, configuration.mLeft,
configuration.mYPosRelativeToView,
configuration.mHeightRelativeToViewHeight,
configuration.mName);
getFragmentManager().beginTransaction().
addToBackStack(null).
add(R.id.container, moveFragment).
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).
commit();
}
@Override
public void performDeleteHotspotAction(HotspotItem configuration) {
mAsyncQueryHandler.deleteHotspot(configuration.mId);
}
@Override
public void performSetHeightHotspotAction(HotspotItem configuration) {
ChangeHotspotHeightFragment fragment = ChangeHotspotHeightFragment.
createInstance(configuration.mId, configuration.mHeightRelativeToViewHeight);
fragment.show(getFragmentManager(), "height_editor");
}
@Override
public Loader<ArrayList<HotspotItem>> onCreateLoader(int id, Bundle args) {
return new HotspotsLoader(this);
}
@Override
public void onLoadFinished(Loader<ArrayList<HotspotItem>> loader,
ArrayList<HotspotItem> data) {
onHotspotsLoaded(data);
}
/**
* Called when the hotspots are loaded from the database
*/
void onHotspotsLoaded(ArrayList<HotspotItem> hotspotItems) {
mHotspotAdapter.setHotspots(hotspotItems);
}
@Override
public void onLoaderReset(Loader<ArrayList<HotspotItem>> loader) {
}
/**
* The adapter showing the hotspots. Forwards the listener to the
* view-holders and handles everything related
*/
static class HotspotAdapter extends RecyclerView.Adapter<AbsHotspotViewHolder>
implements GotItDismissListener {
final HotspotActionListener mActionListener;
final ArrayList<HotspotItem> mHotspotItems = new ArrayList<>();
final SharedPreferences mPreferences;
boolean mGotItDismissed;
HotspotAdapter(HotspotActionListener actionListener, SharedPreferences preferences) {
mActionListener = actionListener;
mPreferences = preferences;
mGotItDismissed = mPreferences.getBoolean("hotspots_got_it_dismissed", false);
}
public HotspotItem getItem(int position) {
return mHotspotItems.get(position);
}
@Override
public AbsHotspotViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
if (viewType == R.layout.got_it_hotspots) {
View view = inflater.inflate(R.layout.got_it_hotspots, parent, false);
return new GotItViewHolder(view, this);
}
View convertView = inflater.inflate(R.layout.hotspot_view, parent, false);
return new HotspotViewHolder(convertView, mActionListener);
}
@Override
public void onBindViewHolder(AbsHotspotViewHolder holder, int position) {
if (!mGotItDismissed && position == 0) {
return;
}
if (!mGotItDismissed) {
position--;
}
HotspotItem configuration = mHotspotItems.get(position);
holder.bind(configuration);
}
@Override
public int getItemViewType(int position) {
if (position == 0 && !mGotItDismissed) {
return R.layout.got_it_hotspots;
}
return super.getItemViewType(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
if (!mGotItDismissed) {
return mHotspotItems.size() + 1;
}
return mHotspotItems.size();
}
public void setHotspots(ArrayList<HotspotItem> hotspotItems) {
mHotspotItems.clear();
mHotspotItems.addAll(hotspotItems);
notifyDataSetChanged();
}
@Override
public void onDismissed() {
if (!mGotItDismissed) {
mGotItDismissed = true;
mPreferences.edit().putBoolean("hotspots_got_it_dismissed", true).apply();
notifyItemRemoved(0);
}
}
}
static class GotItViewHolder extends AbsHotspotViewHolder implements View.OnClickListener {
final GotItDismissListener mGotItDismissListener;
public GotItViewHolder(View itemView, GotItDismissListener l) {
super(itemView);
mGotItDismissListener = l;
View gotItButton = itemView.findViewById(R.id.got_it_button);
gotItButton.setOnClickListener(this);
}
@Override
public void bind(HotspotItem hotspotItem) {
}
@Override
public void onClick(View v) {
mGotItDismissListener.onDismissed();
}
}
/**
* An implementation of the query handler to perform operations on the hotspots with
*/
static class AsyncQueryHandlerImpl extends AsyncQueryHandler {
final int TOKEN_INSERT_HOTSPOT = 0;
final int TOKEN_INSERT_HOTSPOT_PAGE = 1;
final Context mContext;
public AsyncQueryHandlerImpl(Context context) {
super(context.getContentResolver());
mContext = context.getApplicationContext();
}
/**
* Inserts a new hotspot into the database
*/
public void addNewHotspot() {
ContentValues values = new ContentValues();
values.put(HomeContract.Hotspots.ALWAYS_OPEN_LAST, 0);
values.put(HomeContract.Hotspots.NAME,
mContext.getString(R.string.default_hotspot_name));
values.put(HomeContract.Hotspots.LEFT_BORDER, 1);
values.put(HomeContract.Hotspots.NEEDS_CONFIGURATION, 1);
values.put(HomeContract.Hotspots.Y_POSITION, .2f);
values.put(HomeContract.Hotspots.HEIGHT, .2f);
startInsert(TOKEN_INSERT_HOTSPOT, null, HomeContract.Hotspots.CONTENT_URI, values);
}
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
// when we get here, this means we were querying the pages table to
// add link to a newly inserted hotspot.
// The cookie is the uri of the newly inserted hotspot, the cursor
// only contains page ids, so we can get them and insert them one
// by one.
long hotspotId = ContentUris.parseId((Uri) cookie);
int position = 0;
while (cursor.moveToNext()) {
long pageId = cursor.getLong(0);
ContentValues values = new ContentValues();
values.put(HomeContract.HotspotPages.POSITION, position++);
values.put(HomeContract.HotspotPages._HOTPSOT_ID, hotspotId);
values.put(HomeContract.HotspotPages._PAGE_ID, pageId);
startInsert(TOKEN_INSERT_HOTSPOT_PAGE, null,
HomeContract.HotspotPages.CONTENT_URI, values);
}
cursor.close();
}
@Override
protected void onInsertComplete(int token, Object cookie, Uri uri) {
// in case a hotspot was added, start a query to load all pages, so we can link
// them all to the new hotspot
if (token == TOKEN_INSERT_HOTSPOT) {
startQuery(0, uri /* cookie */,
HomeContract.Pages.CONTENT_URI,
new String[]{
HomeContract.Pages._ID
},
null,
null,
null);
}
}
public void deleteHotspot(long id) {
// first delete the hotspot-pages links
startDelete(0, null,
HomeContract.HotspotPages.CONTENT_URI,
HomeContract.HotspotPages._HOTPSOT_ID + "=?",
new String[]{
String.valueOf(id)
});
// then delete the hotspot itself
Uri uri = ContentUris.withAppendedId(HomeContract.Hotspots.CONTENT_URI, id);
startDelete(0, null, uri, null, null);
}
}
}