/*
* Copyright (C) 2014 Eric Butler
*
* 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.tapchatapp.android.app.ui;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import com.tapchatapp.android.app.event.BufferAddedEvent;
import com.tapchatapp.android.app.event.BufferChangedEvent;
import com.tapchatapp.android.app.event.BufferRemovedEvent;
import com.tapchatapp.android.app.event.ServiceStateChangedEvent;
import com.tapchatapp.android.app.fragment.BufferFragment;
import com.tapchatapp.android.app.TapchatApp;
import com.tapchatapp.android.client.TapchatService;
import com.tapchatapp.android.client.model.Buffer;
import com.tapchatapp.android.client.model.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import javax.inject.Inject;
public class BuffersPagerAdapter extends TapchatFragmentStatePagerAdapter {
private static final String KEY_BUFFERS = "com.tapchatapp.android.buffers";
private final long mConnectionId;
private final BuffersToDisplay mDisplay;
private final Object mLock = new Object();
private ArrayList<BufferInfo> mBuffers = new ArrayList<>();
private int mConnectionState;
@Inject Bus mBus;
public BuffersPagerAdapter(Activity activity, long connectionId, BuffersToDisplay display) {
super(activity.getFragmentManager());
TapchatApp.get().inject(this);
mConnectionId = connectionId;
mDisplay = display;
}
public void registerBus() {
mBus.register(this);
}
public void unregisterBus() {
mBus.unregister(this);
}
@Override public Parcelable saveState() {
Bundle bundle = (Bundle) super.saveState();
if (bundle == null) {
bundle = new Bundle();
}
bundle.putParcelableArrayList(KEY_BUFFERS, mBuffers);
return bundle;
}
@Override public void restoreState(Parcelable state, ClassLoader loader) {
super.restoreState(state, loader);
if (state != null && state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mBuffers = bundle.getParcelableArrayList(KEY_BUFFERS);
notifyDataSetChanged();
}
}
@Subscribe public void onServiceStateChanged(ServiceStateChangedEvent event) {
TapchatService service = event.getService();
mConnectionState = service.getConnectionState();
if (mConnectionState != TapchatService.STATE_LOADED) {
return;
}
Connection connection = service.getConnection(mConnectionId);
final ArrayList<BufferInfo> buffers = new ArrayList<>();
// Add new buffers.
if (mDisplay == BuffersToDisplay.ConsoleOnly) {
buffers.add(BufferInfo.forBuffer(connection.getConsoleBuffer()));
} else {
for (Buffer buffer : connection.getBuffers()) {
if ((!buffer.isArchived()) || mDisplay == BuffersToDisplay.ShowArchived) {
buffers.add(BufferInfo.forBuffer(buffer));
}
}
}
Collections.sort(buffers, BufferInfo.COMPARATOR);
mBuffers = buffers;
notifyDataSetChanged();
}
@Subscribe public void onBufferAdded(final BufferAddedEvent event) {
if (event.getConnection().getId() != mConnectionId) {
return;
}
if (mConnectionState != TapchatService.STATE_LOADED) {
return;
}
Buffer buffer = event.getBuffer();
synchronized (mLock) {
if (findBuffer(buffer.getId()) != null) {
return;
}
final ArrayList<BufferInfo> buffers = new ArrayList<>(mBuffers);
buffers.add(BufferInfo.forBuffer(buffer));
Collections.sort(buffers, BufferInfo.COMPARATOR);
mBuffers = buffers;
notifyDataSetChanged();
}
}
@Subscribe public void onBufferChanged(final BufferChangedEvent event) {
if (event.getConnection().getId() != mConnectionId) {
return;
}
if (mConnectionState != TapchatService.STATE_LOADED) {
return;
}
synchronized (mLock) {
Buffer buffer = event.getBuffer();
BufferInfo info = findBuffer(buffer.getId());
if (info != null) {
String newName = buffer.getDisplayName();
int newWeight = buffer.getWeight();
if (buffer.isArchived() && mDisplay == BuffersToDisplay.Normal) {
mBuffers.remove(info);
notifyDataSetChanged();
return;
}
if ((!TextUtils.equals(info.mName, newName)) || info.mWeight != newWeight) {
info.mName = newName;
info.mWeight = newWeight;
Collections.sort(mBuffers, BufferInfo.COMPARATOR);
notifyDataSetChanged();
}
} else {
if ((!buffer.isArchived()) || buffer.isArchived() && mDisplay == BuffersToDisplay.ShowArchived) {
final ArrayList<BufferInfo> buffers = new ArrayList<>(mBuffers);
buffers.add(BufferInfo.forBuffer(buffer));
Collections.sort(buffers, BufferInfo.COMPARATOR);
mBuffers = buffers;
notifyDataSetChanged();
}
}
}
}
@Subscribe public void onBufferRemoved(final BufferRemovedEvent event) {
if (event.getConnection().getId() != mConnectionId) {
return;
}
if (mConnectionState != TapchatService.STATE_LOADED) {
return;
}
Buffer buffer = event.getBuffer();
synchronized (mLock) {
for (int i = 0; i < mBuffers.size(); i++) {
BufferInfo info = mBuffers.get(i);
if (info.getBufferId() == buffer.getId()) {
mBuffers.remove(i);
notifyDataSetChanged();
return;
}
}
}
}
@Override
public int getCount() {
return mBuffers.size();
}
@Override public String getPageTitle(int position) {
return mBuffers.get(position).mName.toUpperCase();
}
@Override public Fragment getItem(int position) {
BufferInfo info = mBuffers.get(position);
return BufferFragment.create(info.getType(), mConnectionId, info.getBufferId());
}
@Override public int getItemPosition(Object object) {
BufferFragment fragment = (BufferFragment) object;
int index = findBufferIndex(fragment.getBufferId());
if (index >= 0) {
return index;
} else {
return POSITION_NONE;
}
}
@Override public String getTag(int position) {
return String.valueOf(mBuffers.get(position).getBufferId());
}
public BufferInfo getBufferInfo(int position) {
return mBuffers.get(position);
}
public int getBufferIndex(long bufferId) {
for (int i = 0; i < mBuffers.size(); i++) {
BufferInfo info = mBuffers.get(i);
if (info.getBufferId() == bufferId) {
return i;
}
}
return -1;
}
private BufferInfo findBuffer(long bufferId) {
synchronized (mLock) {
for (BufferInfo info : mBuffers) {
if (info.getBufferId() == bufferId) {
return info;
}
}
return null;
}
}
public int findBufferIndex(long bufferId) {
synchronized (mLock) {
for (int i = 0; i < mBuffers.size(); i++) {
BufferInfo info = mBuffers.get(i);
if (info.getBufferId() == bufferId) {
return i;
}
}
return -1;
}
}
public enum BuffersToDisplay {
Normal,
ShowArchived,
ConsoleOnly;
public static BuffersToDisplay parseString(String name) {
if (name == null) {
return Normal;
}
switch (name) {
case "archived":
return ShowArchived;
case "console":
return ConsoleOnly;
default:
return Normal;
}
}
}
public static final class BufferInfo implements Parcelable {
private final long mConnectionId;
private final long mBufferId;
private final int mType;
private int mWeight;
private String mName;
public static final Comparator<? super BufferInfo> COMPARATOR = new Comparator<BufferInfo>() {
@Override public int compare(BufferInfo buffer, BufferInfo buffer1) {
Integer weight1 = buffer.getWeight();
Integer weight2 = buffer1.getWeight();
if (weight1.equals(weight2)) {
return buffer.getName().compareToIgnoreCase(buffer1.getName());
} else {
return weight2.compareTo(weight1);
}
}
};
public static final Creator<BufferInfo> CREATOR = new Creator<BufferInfo>() {
@Override public BufferInfo createFromParcel(Parcel source) {
return new BufferInfo(source.readLong(), source.readLong(), source.readInt(), source.readInt(),
source.readString());
}
@Override public BufferInfo[] newArray(int size) {
return new BufferInfo[size];
}
};
public BufferInfo(long cid, long bid, int type, int weight, String name) {
mConnectionId = cid;
mBufferId = bid;
mType = type;
mWeight = weight;
mName = name;
}
public static BufferInfo forBuffer(Buffer buffer) {
return new BufferInfo(buffer.getConnection().getId(), buffer.getId(), buffer.getType(), buffer.getWeight(),
buffer.getDisplayName());
}
public long getConnectionId() {
return mConnectionId;
}
public long getBufferId() {
return mBufferId;
}
public int getType() {
return mType;
}
public String getName() {
return mName;
}
public int getWeight() {
return mWeight;
}
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mConnectionId);
dest.writeLong(mBufferId);
dest.writeInt(mType);
dest.writeInt(mWeight);
dest.writeString(mName);
}
@Override public int describeContents() {
return 0;
}
}
}