/*******************************************************************************
* Copyright 2012 Keith Johnson
*
* 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.ubergeek42.weechat.relay.messagehandler;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ubergeek42.weechat.Buffer;
import com.ubergeek42.weechat.relay.RelayMessageHandler;
import com.ubergeek42.weechat.relay.protocol.Hashtable;
import com.ubergeek42.weechat.relay.protocol.Hdata;
import com.ubergeek42.weechat.relay.protocol.HdataEntry;
import com.ubergeek42.weechat.relay.protocol.RelayObject;
/**
* Manages a list of buffers present in weechat
*
* @author ubergeek42<kj@ubergeek42.com>
*
*/
public class BufferManager implements RelayMessageHandler {
private static Logger logger = LoggerFactory.getLogger("BufferManager");
final private static boolean DEBUG = false;
ArrayList<Buffer> buffers = new ArrayList<Buffer>();
private BuffersChangedObserver onChangeObserver;
/**
* Locate and returns a Buffer object based on it's pointer
*
* @param pointer
* - Pointer to a weechat buffer(e.g. 0xDEADBEEF)
* @return Buffer object for the associated buffer, or null if not found
*/
public Buffer findByPointer(String pointer) {
for (Buffer b : buffers) {
if (pointer.equals(b.getPointer())) {
return b;
}
}
return null;
}
/**
* Locate and returns a Buffer object based on it's name
*
* @param bufferName
* - Name of a weechat buffer(e.g. irc.freenode.#weechat)
* @return Buffer object for the associated buffer, or null if not found
*/
public Buffer findByName(String bufferName) {
for (Buffer b : buffers) {
if (bufferName.equals(b.getFullName())) {
return b;
}
}
return null;
}
/**
* Get the list of buffers
*/
@SuppressWarnings("unchecked")
public ArrayList<Buffer> getBuffersCopy() {
return (ArrayList<Buffer>) buffers.clone();
}
/**
* Get the Buffer at the specified index
*
* @param index
* - The index to retrieve
* @return Buffer object at the given index
*/
public Buffer getBuffer(int index) {
return buffers.get(index);
}
/**
* Gets the number of buffers this manager knows about
*
* @return Number of buffers
*/
public int getNumBuffers() {
return buffers.size();
}
/**
* Register a single observer to be notified when the list of buffers changes
*
* @param bo
* - The observer to receive notifications
*/
public void setOnChangedHandler(BuffersChangedObserver bo) {
if (DEBUG) logger.warn("setOnChangedHandler(...)");
this.onChangeObserver = bo;
}
/**
* Clears the buffer change observer
*/
public void clearOnChangedHandler() {
if (DEBUG) logger.warn("clearOnChangedHandler()");
this.onChangeObserver = null;
}
/**
* Can be called to inform clients that the buffers have changed in some way Currently used for
* notifying about unread lines/highlights
*/
public void buffersChanged() {
if (DEBUG) logger.warn("buffersChanged()");
if (onChangeObserver != null) {
onChangeObserver.onBuffersChanged();
}
}
@Override
public void handleMessage(RelayObject obj, String id) {
if (!(obj instanceof Hdata)) {
if (DEBUG) logger.error("Expected hdata, got {}", obj.getClass());
return;
}
Hdata whdata = (Hdata) obj;
for (int i = 0; i < whdata.getCount(); i++) {
HdataEntry hde = whdata.getItem(i);
if (id.equals("listbuffers")) {
Buffer wb = new Buffer();
wb.setPointer(hde.getPointer());
wb.setNumber(hde.getItem("number").asInt());
wb.setFullName(hde.getItem("full_name").asString());
wb.setShortName(hde.getItem("short_name").asString());
wb.setTitle(hde.getItem("title").asString());
wb.setNicklistVisible(hde.getItem("nicklist").asInt() == 1);
wb.setType(hde.getItem("type").asInt());
wb.setNotifyLevel(hde.getItem("notify").asInt());
Hashtable ht = (Hashtable) hde.getItem("local_variables");
if (ht != null) {
wb.setLocals(ht);
}
buffers.add(wb);
} else if (id.equals("_buffer_opened")) {
Buffer wb = new Buffer();
wb.setPointer(hde.getPointer());
wb.setNumber(hde.getItem("number").asInt());
wb.setFullName(hde.getItem("full_name").asString());
wb.setShortName(hde.getItem("short_name").asString());
wb.setTitle(hde.getItem("title").asString());
wb.setNicklistVisible(hde.getItem("nicklist").asInt() == 1);
// also get "prev_buffer", "next_buffer", and "local_variables"
// Don't get "type" though
buffers.add(wb);
} else {
Buffer wb = findByPointer(hde.getPointer(0));
if (wb == null) {
if (DEBUG) logger.error("Unable to find buffer to update");
return;
}
if (id.equals("_buffer_type_changed")) {
wb.setType(hde.getItem("type").asInt());
wb.setNumber(hde.getItem("number").asInt());
wb.setFullName(hde.getItem("full_name").asString());
} else if (id.equals("_buffer_moved") || id.equals("_buffer_merged")
|| id.equals("_buffer_unmerged")) {
wb.setNumber(hde.getItem("number").asInt());
wb.setFullName(hde.getItem("full_name").asString());
} else if (id.equals("_buffer_renamed") || id.equals("_buffer_title_changed")) {
wb.setNumber(hde.getItem("number").asInt());
wb.setFullName(hde.getItem("full_name").asString());
if (id.equals("_buffer_title_changed")) {
wb.setTitle(hde.getItem("title").asString());
} else {
wb.setShortName(hde.getItem("short_name").asString());
Hashtable ht = (Hashtable) hde.getItem("local_variables");
if (ht != null) {
wb.setLocals(ht);
}
}
} else if (id.equals("_buffer_localvar_added")
|| id.equals("_buffer_localvar_changed")
|| id.equals("_buffer_localvar_removed")) {
wb.setNumber(hde.getItem("number").asInt());
wb.setFullName(hde.getItem("full_name").asString());
Hashtable ht = (Hashtable) hde.getItem("local_variables");
if (ht != null) {
wb.setLocals(ht);
}
} else if (id.equals("_buffer_closing")) {
for (int j = 0; j < buffers.size(); j++) {
if (buffers.get(j).getPointer().equals(hde.getPointer())) {
Buffer b = buffers.remove(j);
b.destroy();
break;
}
}
} else {
if (DEBUG) logger.warn("Unknown message ID: '{}'", id);
}
}
}
buffersChanged();
}
}