/*
* Author: Balch
* Created: 8/15/16 6:38 AM
*
* This file is part of MockTrade.
*
* MockTrade 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.
*
* MockTrade 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.
*
* You should have received a copy of the GNU General Public License
* along with MockTrade. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2016
*
*/
package com.balch.mocktrade;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.wearable.view.BoxInsetLayout;
import android.support.wearable.view.CircledImageView;
import android.support.wearable.view.WearableListView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.balch.mocktrade.shared.WatchConfigItem;
import com.balch.mocktrade.shared.WearDataSync;
import com.balch.mocktrade.shared.utils.VersionUtils;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.DataItem;
import com.google.android.gms.wearable.DataItemBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
import java.util.ArrayList;
import java.util.List;
public class MockTradeWatchConfigActivity extends Activity implements
WearableListView.ClickListener, WearableListView.OnScrollListener,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "MockTradeWatchConfig";
private GoogleApiClient mGoogleApiClient;
private LinearLayout mHeader;
private ConfigItemAdapter mConfigItemAdapter;
private Node mCompanionNode;
private RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
float newTranslation = Math.min(-dx, 0);
mHeader.setTranslationY(newTranslation);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.config_watchface_activity);
TextView version = (TextView) findViewById(R.id.config_watch_version);
version.setText("Version: " + VersionUtils.getVersion(this, BuildConfig.DEBUG));
mHeader = (LinearLayout) findViewById(R.id.config_watch_header);
BoxInsetLayout content = (BoxInsetLayout) findViewById(R.id.content);
// BoxInsetLayout adds padding by default on round devices. Add some on square devices.
content.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
if (!insets.isRound()) {
v.setPaddingRelative(
getResources().getDimensionPixelSize(R.dimen.content_padding_start),
v.getPaddingTop(),
v.getPaddingEnd(),
v.getPaddingBottom());
}
return v.onApplyWindowInsets(insets);
}
});
WearableListView listView = (WearableListView) findViewById(R.id.config_watch_list);
listView.setHasFixedSize(true);
listView.setClickListener(this);
listView.addOnScrollListener(this);
mConfigItemAdapter = new ConfigItemAdapter(new ConfigItemAdapter.ConfigItemAdapterListener() {
@Override
public void onConfigItemChanged(WatchConfigItem item) {
if (mCompanionNode != null && mGoogleApiClient!=null && mGoogleApiClient.isConnected()) {
Wearable.MessageApi.sendMessage(mGoogleApiClient, mCompanionNode.getId(),
WearDataSync.MSG_WATCH_CONFIG_SET, item.toDataMap().toByteArray()).setResultCallback(
new ResultCallback<MessageApi.SendMessageResult>() {
@Override
public void onResult(@NonNull MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e("TAG", "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
}
}
}
);
}
}
});
listView.setAdapter(mConfigItemAdapter);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Wearable.API)
.build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
super.onStop();
}
@Override // WearableListView.ClickListener
public void onClick(WearableListView.ViewHolder viewHolder) {
// ConfigItemViewHolder configItemViewHolder = (ConfigItemViewHolder) viewHolder;
// updateConfigDataItem(configItemViewHolder.mConfigItem);
finish();
}
@Override // WearableListView.ClickListener
public void onTopEmptyRegionClick() {}
@Override // WearableListView.OnScrollListener
public void onScroll(int scroll) {}
@Override // WearableListView.OnScrollListener
public void onAbsoluteScrollChange(int scroll) {
float newTranslation = Math.min(-scroll, 0);
mHeader.setTranslationY(newTranslation);
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult result) {
Log.e(TAG, "onConnectionFailed: " + result);
}
@Override
public void onConnected(Bundle connectionHint) {
Log.d(TAG, "onConnected: " + connectionHint);
mCompanionNode = null;
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(@NonNull NodeApi.GetConnectedNodesResult nodesResult) {
List<Node> nodes = nodesResult.getNodes();
if (!nodes.isEmpty()) {
for (Node node : nodes) {
if (node.isNearby()) {
mCompanionNode = node;
break;
}
if (mCompanionNode == null) {
mCompanionNode = nodes.get(0);
}
}
}
mCompanionNode = !nodes.isEmpty() ? nodes.get(0) : null;
}
});
PendingResult<DataItemBuffer> results = Wearable.DataApi.getDataItems(mGoogleApiClient);
results.setResultCallback(new ResultCallback<DataItemBuffer>() {
@Override
public void onResult(@NonNull DataItemBuffer dataItems) {
for (int x = 0; x < dataItems.getCount(); x++) {
DataItem dataItem = dataItems.get(x);
DataMapItem dataMapItem = DataMapItem.fromDataItem(dataItem);
DataMap dataMap = dataMapItem.getDataMap();
String uriPath = dataItem.getUri().getPath();
if (uriPath.equals(WearDataSync.PATH_WATCH_CONFIG_SYNC)) {
ArrayList<DataMap> dataMapList = dataMap.getDataMapArrayList(WearDataSync.DATA_WATCH_CONFIG_DATA_ITEMS);
if (dataMapList != null) {
for (DataMap dm : dataMapList) {
mConfigItemAdapter.add(new WatchConfigItem(dm));
}
mConfigItemAdapter.notifyDataSetChanged();
}
}
}
dataItems.release();
}
});
}
@Override
public void onConnectionSuspended(int cause) {
}
@Override // WearableListView.OnScrollListener
public void onScrollStateChanged(int scrollState) {}
@Override // WearableListView.OnScrollListener
public void onCentralPositionChanged(int centralPosition) {}
private static class ConfigItemAdapter extends WearableListView.Adapter {
private final ConfigItemAdapterListener listener;
private List<WatchConfigItem> mConfigItems = new ArrayList<>();
ConfigItemAdapter(ConfigItemAdapterListener listener) {
this.listener = listener;
}
public void add(WatchConfigItem item) {
this.mConfigItems.add(item);
}
public void addAll(List<WatchConfigItem> items) {
this.mConfigItems.addAll(items);
}
@Override
public ConfigItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ConfigItemViewHolder(new ConfigItemView(parent.getContext()));
}
@Override
public void onBindViewHolder(WearableListView.ViewHolder holder, final int position) {
final ConfigItemViewHolder configItemViewHolder = (ConfigItemViewHolder) holder;
final WatchConfigItem configItem = mConfigItems.get(position);
configItemViewHolder.mConfigItem.bind(configItem, new View.OnClickListener() {
@Override
public void onClick(View v) {
configItem.setEnabled(!configItem.isEnabled());
configItemViewHolder.mConfigItem.setConfigItemEnabled(configItem.isEnabled());
listener.onConfigItemChanged(configItem);
}
});
RecyclerView.LayoutParams layoutParams =
new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
int itemMargin = (int) ((ConfigItemViewHolder) holder).itemView.getResources()
.getDimension(R.dimen.digital_config_color_picker_item_margin);
// Add margins to first and last item to make it possible for user to tap on them.
if (position == 0) {
layoutParams.setMargins(0, itemMargin, 0, 0);
} else if (position == mConfigItems.size() - 1) {
layoutParams.setMargins(0, 0, 0, itemMargin);
} else {
layoutParams.setMargins(0, 0, 0, 0);
}
configItemViewHolder.itemView.setLayoutParams(layoutParams);
}
@Override
public int getItemCount() {
return mConfigItems.size();
}
interface ConfigItemAdapterListener {
void onConfigItemChanged(WatchConfigItem item);
}
}
private static class ConfigItemView extends LinearLayout {
private final TextView mDescription;
private final CircledImageView mEnabledImage;
public ConfigItemView(Context context) {
super(context);
View.inflate(context, R.layout.config_watchface_item, this);
mDescription = (TextView) findViewById(R.id.config_watch_item_text);
mEnabledImage = (CircledImageView) findViewById(R.id.config_watch_item_image);
}
public void bind(WatchConfigItem item, OnClickListener clickListener) {
mDescription.setText(item.getDescription());
mEnabledImage.setOnClickListener(clickListener);
setConfigItemEnabled(item.isEnabled());
}
public void setConfigItemEnabled(boolean enabled) {
mEnabledImage.setImageResource(enabled ? R.drawable.sign_check : R.drawable.sign_error);
}
}
private static class ConfigItemViewHolder extends WearableListView.ViewHolder {
private final ConfigItemView mConfigItem;
ConfigItemViewHolder(ConfigItemView configItem) {
super(configItem);
mConfigItem = configItem;
}
}
}