/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare 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 Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui;
import com.google.inject.Inject;
import io.bitsquare.app.Version;
import io.bitsquare.common.persistance.Persistable;
import io.bitsquare.gui.common.view.View;
import io.bitsquare.gui.common.view.ViewPath;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.market.MarketView;
import io.bitsquare.storage.Storage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
public final class Navigation implements Persistable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
private static final Logger log = LoggerFactory.getLogger(Navigation.class);
private static final ViewPath DEFAULT_VIEW_PATH = ViewPath.to(MainView.class, MarketView.class);
public interface Listener {
void onNavigationRequested(ViewPath path);
}
// New listeners can be added during iteration so we use CopyOnWriteArrayList to
// prevent invalid array modification
transient private final CopyOnWriteArraySet<Listener> listeners = new CopyOnWriteArraySet<>();
transient private final Storage<Navigation> storage;
transient private ViewPath currentPath;
// Used for returning to the last important view. After setup is done we want to
// return to the last opened view (e.g. sell/buy)
transient private ViewPath returnPath;
// Persisted fields
private ViewPath previousPath;
@Inject
public Navigation(Storage<Navigation> storage) {
this.storage = storage;
storage.setNumMaxBackupFiles(3);
Navigation persisted = storage.initAndGetPersisted(this);
if (persisted != null) {
previousPath = persisted.getPreviousPath();
} else
previousPath = DEFAULT_VIEW_PATH;
// need to be null initially and not DEFAULT_VIEW_PATH to navigate through all items
currentPath = null;
}
@SuppressWarnings("unchecked")
public void navigateTo(Class<? extends View>... viewClasses) {
navigateTo(ViewPath.to(viewClasses));
}
public void navigateTo(ViewPath newPath) {
if (newPath == null)
return;
ArrayList<Class<? extends View>> temp = new ArrayList<>();
for (int i = 0; i < newPath.size(); i++) {
Class<? extends View> viewClass = newPath.get(i);
temp.add(viewClass);
if (currentPath == null ||
(currentPath != null &&
currentPath.size() > i &&
viewClass != currentPath.get(i) &&
i != newPath.size() - 1)) {
ArrayList<Class<? extends View>> temp2 = new ArrayList<>(temp);
for (int n = i + 1; n < newPath.size(); n++) {
Class<? extends View>[] newTemp = new Class[i + 1];
currentPath = ViewPath.to(temp2.toArray(newTemp));
navigateTo(currentPath);
viewClass = newPath.get(n);
temp2.add(viewClass);
}
}
}
currentPath = newPath;
previousPath = currentPath;
storage.queueUpForSave(1000);
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
}
public void navigateToPreviousVisitedView() {
if (previousPath == null || previousPath.size() == 0)
previousPath = DEFAULT_VIEW_PATH;
navigateTo(previousPath);
}
public void addListener(Listener listener) {
listeners.add(listener);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
}
public ViewPath getReturnPath() {
return returnPath;
}
public ViewPath getCurrentPath() {
return currentPath;
}
public void setReturnPath(ViewPath returnPath) {
this.returnPath = returnPath;
}
private ViewPath getPreviousPath() {
return previousPath;
}
}