/*
* Copyright (C) 2016 Haruki Hasegawa
*
* 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.h6ah4i.android.widget.advrecyclerview.composedadapter;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import com.h6ah4i.android.widget.advrecyclerview.adapter.BridgeAdapterDataObserver;
import java.util.ArrayList;
import java.util.List;
class AdaptersSet {
public static long NO_SEGMENTED_POSITION = -1L;
private BridgeAdapterDataObserver.Subscriber mSubscriber;
private List<ComposedChildAdapterTag> mAdapterTags;
private List<RecyclerView.Adapter> mAdapters;
private List<RecyclerView.Adapter> mUniqueAdapters;
private List<ComposedChildAdapterDataObserver> mObservers;
public AdaptersSet(BridgeAdapterDataObserver.Subscriber bridgeSubscriber) {
mSubscriber = bridgeSubscriber;
mAdapterTags = new ArrayList<>();
mAdapters = new ArrayList<>();
mUniqueAdapters = new ArrayList<>();
mObservers = new ArrayList<>();
}
public ComposedChildAdapterTag addAdapter(@NonNull RecyclerView.Adapter adapter, int position) {
final ComposedChildAdapterTag tag = new ComposedChildAdapterTag();
mAdapterTags.add(position, tag);
mAdapters.add(position, adapter);
ComposedChildAdapterDataObserver observer;
final int uniqueAdapterIndex = mUniqueAdapters.indexOf(adapter);
if (uniqueAdapterIndex >= 0) {
observer = mObservers.get(uniqueAdapterIndex);
} else {
observer = new ComposedChildAdapterDataObserver(mSubscriber, adapter);
mObservers.add(observer);
mUniqueAdapters.add(adapter);
adapter.registerAdapterDataObserver(observer);
}
observer.registerChildAdapterTag(tag);
return tag;
}
public RecyclerView.Adapter removeAdapter(@NonNull ComposedChildAdapterTag tag) {
final int segment = getAdapterSegment(tag);
if (segment < 0) {
return null;
}
final RecyclerView.Adapter adapter = mAdapters.remove(segment);
mAdapterTags.remove(segment);
final int uniqueAdapterIndex = mUniqueAdapters.indexOf(adapter);
if (uniqueAdapterIndex < 0) {
throw new IllegalStateException("Something wrong. Inconsistency detected.");
}
final ComposedChildAdapterDataObserver observer = mObservers.get(uniqueAdapterIndex);
observer.unregisterChildAdapterTag(tag);
if (!observer.hasChildAdapters()) {
adapter.unregisterAdapterDataObserver(observer);
}
return adapter;
}
public int getAdapterSegment(ComposedChildAdapterTag tag) {
return mAdapterTags.indexOf(tag);
}
public int getSegmentCount() {
return mAdapters.size();
}
public RecyclerView.Adapter getAdapter(int segment) {
return mAdapters.get(segment);
}
public ComposedChildAdapterTag getTag(int segment) {
return mAdapterTags.get(segment);
}
public static int extractSegment(long segmentedPosition) {
return (int) (segmentedPosition >>> 32);
}
public static int extractSegmentOffset(long segmentedPosition) {
return (int) (segmentedPosition & 0xFFFFFFFFL);
}
public static long composeSegmentedPosition(int segment, int offset) {
return (((long) segment) << 32) | (offset & 0xFFFFFFFFL);
}
public void release() {
mAdapterTags.clear();
mAdapters.clear();
int numUniqueAdapters = mUniqueAdapters.size();
for (int i = 0; i < numUniqueAdapters; i++) {
ComposedChildAdapterDataObserver observer = mObservers.get(i);
RecyclerView.Adapter adapter = mUniqueAdapters.get(i);
adapter.unregisterAdapterDataObserver(observer);
observer.release();
}
mUniqueAdapters.clear();
mObservers.clear();
}
public List<RecyclerView.Adapter> getUniqueAdaptersList() {
return mUniqueAdapters;
}
}