/*
* Copyright 2016 Kejun Xia
*
* 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.shipdream.lib.android.mvc;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Navigation model state keeper implemented by Android parcelable.
*/
public class NavigationModelKeeper implements AndroidModelKeeper<NavigationManager.Model> {
@Override
public Parcelable saveModel(NavigationManager.Model model, Class<NavigationManager.Model> modelType) {
return new ModelParcelable(model);
}
@Override
public NavigationManager.Model getModel(Parcelable parceledModel, Class<NavigationManager.Model> modelType) {
return ((ModelParcelable) parceledModel).model;
}
//==================================================================================================
//Parcelable to manage navigation model
public static class ModelParcelable implements Parcelable {
private NavigationManager.Model model;
public static final Parcelable.Creator<ModelParcelable> CREATOR
= new Parcelable.Creator<ModelParcelable>() {
public ModelParcelable createFromParcel(Parcel in) {
return new ModelParcelable(in);
}
public ModelParcelable[] newArray(int size) {
return new ModelParcelable[size];
}
};
private ModelParcelable(NavigationManager.Model model) {
this.model = model;
}
private ModelParcelable(Parcel in) {
model = new NavigationManager.Model();
int start = in.dataPosition();
int size = in.readInt();
int end = start + size;
if(in.dataPosition() < end) {
String locId = in.readString();
NavLocation location = new NavLocation();
location._setLocationId(locId);
model.setCurrentLocation(location);
readLocation(in, location, end);
}
}
private void readLocation(Parcel in, NavLocation curLoc, int end) {
int pos = in.dataPosition();
if(pos < end) {
String str = in.readString();
NavLocation location = new NavLocation();
location._setLocationId(str);
curLoc._setPreviousLocation(location);
readLocation(in, location, end);
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
//Place holder for the size of the parcel
int start = dest.dataPosition();
dest.writeInt(0);
writeLocation(dest, model.getCurrentLocation());
int end = dest.dataPosition();
//Rewind back and write the size of the parcel
int size = end - start;
dest.setDataPosition(start);
dest.writeInt(size);
//Move the cursor back
dest.setDataPosition(end);
}
private void writeLocation(Parcel dest, NavLocation location) {
if (location != null) {
dest.writeString(location.getLocationId());
writeLocation(dest, location.getPreviousLocation());
}
}
}
}