package de.tum.in.tumcampusapp.activities;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import com.google.common.base.Optional;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.List;
import de.tum.in.tumcampusapp.R;
import de.tum.in.tumcampusapp.activities.generic.ActivityForLoadingInBackground;
import de.tum.in.tumcampusapp.adapters.ChatRoomListAdapter;
import de.tum.in.tumcampusapp.adapters.NoResultsAdapter;
import de.tum.in.tumcampusapp.api.TUMCabeClient;
import de.tum.in.tumcampusapp.auxiliary.Const;
import de.tum.in.tumcampusapp.auxiliary.Utils;
import de.tum.in.tumcampusapp.exceptions.NoPrivateKey;
import de.tum.in.tumcampusapp.managers.ChatRoomManager;
import de.tum.in.tumcampusapp.models.tumcabe.ChatMember;
import de.tum.in.tumcampusapp.models.tumcabe.ChatRoom;
import de.tum.in.tumcampusapp.models.tumcabe.ChatVerification;
import de.tum.in.tumcampusapp.models.tumo.LecturesSearchRow;
import de.tum.in.tumcampusapp.models.tumo.LecturesSearchRowSet;
import de.tum.in.tumcampusapp.tumonline.TUMOnlineConst;
import de.tum.in.tumcampusapp.tumonline.TUMOnlineRequest;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
* This activity presents the chat rooms of user's
* lectures using the TUMOnline web service
*/
public class ChatRoomsActivity extends ActivityForLoadingInBackground<Void, Cursor> implements OnItemClickListener {
private static final String PROPERTY_APP_VERSION = "appVersion";
private StickyListHeadersListView lvMyChatRoomList;
private ChatRoom currentChatRoom;
private ChatMember currentChatMember;
private TUMOnlineRequest<LecturesSearchRowSet> requestHandler;
private ChatRoomManager manager;
private int mCurrentMode = 1;
private ChatRoomListAdapter adapter;
private boolean firstLoad = true;
public ChatRoomsActivity() {
super(R.layout.activity_chat_rooms);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// bind UI elements
lvMyChatRoomList = (StickyListHeadersListView) findViewById(R.id.lvMyChatRoomList);
lvMyChatRoomList.setOnItemClickListener(this);
manager = new ChatRoomManager(this);
//Load the lectures list
requestHandler = new TUMOnlineRequest<>(TUMOnlineConst.LECTURES_PERSONAL, this, true);
TabLayout tabLayout = (TabLayout) findViewById(R.id.chat_rooms_tabs);
// Create a tab listener that is called when the user changes tabs.
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
// show the given tab
mCurrentMode = 1 - tab.getPosition();
firstLoad = true;
startLoading();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
// hide the given tab
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
// probably ignore this event
}
});
tabLayout.addTab(tabLayout.newTab().setText(R.string.joined));
tabLayout.addTab(tabLayout.newTab().setText(R.string.not_joined));
}
@Override
protected void onResume() {
super.onResume();
firstLoad = true;
startLoading();
}
/**
* Gets the saved local information for the user
*/
private void populateCurrentChatMember() {
if (currentChatMember == null) {
currentChatMember = Utils.getSetting(this, Const.CHAT_MEMBER, ChatMember.class);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_activity_chat_rooms, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int i = item.getItemId();
if (i == R.id.action_add_chat_room) {
newChatRoom();
return true;
} else if (i == R.id.action_join_chat_room) {
startActivityForResult(new Intent(this, JoinRoomScanActivity.class), 1);
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK && data != null) {
String name = data.getStringExtra("name");
if (name.charAt(3) == ':') {
createOrJoinChatRoom(name);
} else {
Utils.showToast(this, R.string.invalid_chat_room);
}
}
}
/**
* Prompt the user to type in a name for the new chat room
*/
private void newChatRoom() {
// Set an EditText view to get user input
final EditText input = new EditText(this);
new AlertDialog.Builder(this)
.setTitle(R.string.new_chat_room)
.setMessage(R.string.new_chat_room_desc)
.setView(input)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString();
String randId = Integer.toHexString((int) (Math.random() * 4096));
createOrJoinChatRoom(randId + ':' + value);
}
})
.setNegativeButton(android.R.string.cancel, null).show();
}
/**
* Creates a given chat room if it does not exist and joins it
* Works asynchronously.
*/
private void createOrJoinChatRoom(String name) {
if (this.currentChatMember == null) {
Utils.showToast(this, getString(R.string.chat_not_setup));
return;
}
Utils.logv("create or join chat room " + name);
currentChatRoom = new ChatRoom(name);
try {
TUMCabeClient.getInstance(this).createRoom(currentChatRoom, new ChatVerification(this, this.currentChatMember), new Callback<ChatRoom>() {
@Override
public void onResponse(Call<ChatRoom> call, Response<ChatRoom> response) {
if (!response.isSuccessful()) {
Utils.logv("Error creating&joining chat room: " + response.message());
return;
}
// The POST request is successful: go to room. API should have auto joined it
Utils.logv("Success creating&joining chat room: " + response.body());
currentChatRoom = response.body();
manager.join(currentChatRoom);
// When we show joined chat rooms open chat room directly
if (mCurrentMode == 1) {
moveToChatActivity();
} else { //Otherwise show a nice information, that we added the room
final Cursor newCursor = manager.getAllByStatus(mCurrentMode);
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.changeCursor(newCursor);
Utils.showToast(ChatRoomsActivity.this, R.string.joined_chat_room);
}
});
}
}
@Override
public void onFailure(Call<ChatRoom> call, Throwable t) {
Utils.log(t, "Failure creating/joining chat room - trying to GET it from the server");
Utils.showToastOnUIThread(ChatRoomsActivity.this, R.string.activate_key);
}
});
} catch (NoPrivateKey noPrivateKey) {
this.finish();
}
}
@Override
protected Cursor onLoadInBackground(Void... arg) {
if (!firstLoad) {
Optional<LecturesSearchRowSet> lecturesList = requestHandler.fetch();
if (lecturesList.isPresent()) {
List<LecturesSearchRow> lectures = lecturesList.get().getLehrveranstaltungen();
manager.replaceInto(lectures);
}
}
this.populateCurrentChatMember();
// Try to restore joined chat rooms from server
if (!firstLoad && currentChatMember != null) {
try {
List<ChatRoom> rooms = TUMCabeClient.getInstance(this).getMemberRooms(currentChatMember.getId(), new ChatVerification(this, currentChatMember));
manager.replaceIntoRooms(rooms);
} catch (NoPrivateKey e) {
this.finish();
} catch (IOException e) {
Utils.log(e);
}
}
firstLoad = false;
return manager.getAllByStatus(mCurrentMode);
}
@Override
protected void onLoadFinished(Cursor result) {
showLoadingEnded();
if (result.getCount() == 0) {
lvMyChatRoomList.setAdapter(new NoResultsAdapter(this));
} else {
// set ListView to data via the LecturesListAdapter
adapter = new ChatRoomListAdapter(this, result, mCurrentMode);
lvMyChatRoomList.setAdapter(adapter);
}
}
/**
* Handle click on chat room
*/
@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
if (firstLoad) {
return;
}
Cursor item = (Cursor) lvMyChatRoomList.getItemAtPosition(position);
// set bundle for LectureDetails and show it
Bundle bundle = new Bundle();
final Intent intent = new Intent(this, ChatActivity.class);
intent.putExtras(bundle);
String chatRoomUid = item.getString(ChatRoomManager.COL_SEMESTER_ID) + ':' + item.getString(ChatRoomManager.COL_NAME);
this.createOrJoinChatRoom(chatRoomUid);
}
/**
* Opens {@link ChatActivity}
*/
private void moveToChatActivity() {
// We need to move to the next activity now and provide the necessary data for it
// We are sure that both currentChatRoom and currentChatMember exist
Intent intent = new Intent(this, ChatActivity.class);
intent.putExtra(Const.CURRENT_CHAT_ROOM, new Gson().toJson(currentChatRoom));
startActivity(intent);
}
}