/*
* ShareNav - Copyright (c) 2009
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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.
*
* See file COPYING.
*/
package net.sharenav.gps.location;
import java.util.Enumeration;
import java.util.Vector;
import de.enough.polish.util.Locale;
import net.sharenav.gps.Satellite;
import net.sharenav.sharenav.data.Position;
import net.sharenav.util.Logger;
/**
* Wrapper that wraps a List of LocationMsgReceivers in a way that Classes can
* use it like a single LocationMsgReceiver
*
* @author jan rose
*
*/
public class LocationMsgReceiverList implements LocationMsgReceiver {
private final static Logger logger =
Logger.getInstance(LocationMsgReceiverList.class, Logger.DEBUG);
/**
* Vector of all the LocationMsgReceivers
*/
private final Vector mReceiverList;
private volatile byte mCurrentStatus;
private volatile String mCurrentStatusString = "";
private volatile int mCurrentNumSats;
public LocationMsgReceiverList() {
mReceiverList = new Vector(2);
}
public void locationDecoderEnd() {
Enumeration en = mReceiverList.elements();
LocationMsgReceiver receiver;
while (en.hasMoreElements()) {
receiver = (LocationMsgReceiver) en.nextElement();
receiver.locationDecoderEnd();
}
}
public void locationDecoderEnd(String msg) {
Enumeration en = mReceiverList.elements();
LocationMsgReceiver receiver;
while (en.hasMoreElements()) {
receiver = (LocationMsgReceiver) en.nextElement();
receiver.locationDecoderEnd(msg);
}
}
public void receiveMessage(String msg) {
Enumeration en = mReceiverList.elements();
LocationMsgReceiver receiver;
while (en.hasMoreElements()) {
receiver = (LocationMsgReceiver) en.nextElement();
receiver.receiveMessage(msg);
}
}
public void receivePosition(Position pos) {
Enumeration en = mReceiverList.elements();
LocationMsgReceiver receiver;
while (en.hasMoreElements()) {
receiver = (LocationMsgReceiver) en.nextElement();
receiver.receivePosition(pos);
}
}
public void receiveStatus(byte status, int satsReceived) {
mCurrentStatus = status;
mCurrentNumSats = satsReceived;
switch (mCurrentStatus)
{
case LocationMsgReceiver.STATUS_OFF:
mCurrentStatusString = Locale.get("solution.Off");
break;
case LocationMsgReceiver.STATUS_SECEX:
mCurrentStatusString = Locale.get("solution.SecEx");
break;
case LocationMsgReceiver.STATUS_NOFIX:
mCurrentStatusString = Locale.get("solution.NoFix")
+ ((mCurrentNumSats != 0) ? mCurrentNumSats + "S" : "");
break;
case LocationMsgReceiver.STATUS_RECONNECT:
mCurrentStatusString = Locale.get("solution.tildes");
break;
case LocationMsgReceiver.STATUS_ON:
mCurrentStatusString = ((mCurrentNumSats != 0) ? mCurrentNumSats + "S" : Locale.get("solution.On"));
break;
case LocationMsgReceiver.STATUS_2D:
mCurrentStatusString = mCurrentNumSats + "S";
break;
case LocationMsgReceiver.STATUS_3D:
mCurrentStatusString = mCurrentNumSats + "S";
break;
case LocationMsgReceiver.STATUS_DGPS:
mCurrentStatusString = "D" + mCurrentNumSats + "S";
break;
case LocationMsgReceiver.STATUS_CELLID:
mCurrentStatusString = Locale.get("solution.Cell");
break;
case LocationMsgReceiver.STATUS_MANUAL:
mCurrentStatusString = Locale.get("solution.ManualLoc");
break;
}
Enumeration en = mReceiverList.elements();
LocationMsgReceiver receiver;
while (en.hasMoreElements()) {
receiver = (LocationMsgReceiver) en.nextElement();
receiver.receiveStatus(status, satsReceived);
}
}
public byte getCurrentStatus() {
return mCurrentStatus;
}
/** Returns the string representation of the current location status and number
* of satellites received.
*
* @return Status as string representation in the current UI language
*/
public String getCurrentStatusString() {
return mCurrentStatusString;
}
public int getNumSats() {
return mCurrentNumSats;
}
/** Checks if the current position is valid.
* Note that a CellID-based location is not considered valid as it is only a rough
* position which is not good enough e.g. for waypoints.
*
* @return True if position is good, false if it isn't.
*/
public boolean isPosValid() {
return (mCurrentStatus == STATUS_ON) || (mCurrentStatus == STATUS_2D)
|| (mCurrentStatus == STATUS_3D) || (mCurrentStatus == STATUS_DGPS)
|| (mCurrentStatus == STATUS_MANUAL);
}
/** Returns the string representation of the location status.
* It is only a temporary solution that the caller needs to pass the current
* status and satsReceived, but it is currently necessary because callers
* don't have access to this class's instance.
* Instead, it should be possible for callers to get everything centrally from this
* class, which will avoid recalculations.
* The same applies for isPosValid(byte status).
*
* @param status Status for which to generate the string
* @param satsReceived Number of sats to use to generate the string
* @return Status as string representation in the current UI language
*/
public static String getCurrentStatusString(byte status, int satsReceived) {
switch (status)
{
case LocationMsgReceiver.STATUS_OFF:
default:
return Locale.get("solution.Off");
case LocationMsgReceiver.STATUS_SECEX:
return Locale.get("solution.SecEx");
case LocationMsgReceiver.STATUS_NOFIX:
return Locale.get("solution.NoFix")
+ ((satsReceived != 0) ? satsReceived + "S" : "");
case LocationMsgReceiver.STATUS_RECONNECT:
return Locale.get("solution.tildes");
case LocationMsgReceiver.STATUS_ON: // JSR-179, num of sats unknown
return ((satsReceived != 0) ? satsReceived + "S" : Locale.get("solution.On"));
case LocationMsgReceiver.STATUS_2D:
return satsReceived + "S";
case LocationMsgReceiver.STATUS_3D:
return satsReceived + "S";
case LocationMsgReceiver.STATUS_DGPS:
return "D" + satsReceived + "S";
case LocationMsgReceiver.STATUS_CELLID:
return Locale.get("solution.Cell");
case LocationMsgReceiver.STATUS_MANUAL:
return Locale.get("solution.ManualLoc");
}
}
/** Checks if position is valid.
* Only temporary, see the note for getCurrentStatusString(byte status, int satsReceived).
*
* @param status Status to check
* @return True if position is valid, false if it isn't
*/
public static boolean isPosValid(byte status) {
return (status == STATUS_ON) || (status == STATUS_2D)
|| (status == STATUS_3D) || (status == STATUS_DGPS)
|| (status == STATUS_MANUAL);
}
public void receiveSatellites(Satellite[] sats) {
Enumeration en = mReceiverList.elements();
LocationMsgReceiver receiver;
while (en.hasMoreElements()) {
receiver = (LocationMsgReceiver) en.nextElement();
receiver.receiveSatellites(sats);
}
}
public void receiveStatistics(int[] statRecord, byte quality) {
Enumeration en = mReceiverList.elements();
LocationMsgReceiver receiver;
while (en.hasMoreElements()) {
receiver = (LocationMsgReceiver) en.nextElement();
receiver.receiveStatistics(statRecord, quality);
}
}
/**
* add a receiver to the List
*
* @param rec
* LocationMsgReceiver to add
*/
public void addReceiver(LocationMsgReceiver receiver) {
//#debug info
logger.info("Adding a location receiver to the list (" + receiver + ")");
mReceiverList.addElement(receiver);
}
/**
* remove a given receiver from the List
*
* @param rec
* LocationMsgReceiver to be removed
*/
public boolean removeReceiver(LocationMsgReceiver receiver) {
//#debug info
logger.info("Removing location receiver from the list (" + receiver + ")");
// should be safe to remove the first occurrence
return mReceiverList.removeElement(receiver);
}
}