/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * 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.android.server.status;

import android.os.IBinder;
import android.util.Slog;
import android.view.View;
import java.util.ArrayList;

class NotificationViewList {
    private ArrayList<StatusBarNotification> mOngoing = new ArrayList();
    private ArrayList<StatusBarNotification> mLatest = new ArrayList();

    NotificationViewList() {
    }

    private static final int indexInList(ArrayList<StatusBarNotification> list, NotificationData n){
        final int N = list.size();
        for (int i=0; i<N; i++) {
            StatusBarNotification that = list.get(i);
            if (that.data == n) {
                return i;
            }
        }
        return -1;
    }

    int getIconIndex(NotificationData n) {
        final int ongoingSize = mOngoing.size();
        final int latestSize = mLatest.size();
        if (n.ongoingEvent) {
            int index = indexInList(mOngoing, n);
            if (index >= 0) {
                return latestSize + index + 1;
            } else {
                return -1;
            }
        } else {
            return indexInList(mLatest, n) + 1;
        }
    }

    void remove(StatusBarNotification notification) {
        NotificationData n = notification.data;
        int index;
        index = indexInList(mOngoing, n);
        if (index >= 0) {
            mOngoing.remove(index);
            return;
        }
        index = indexInList(mLatest, n);
        if (index >= 0) {
            mLatest.remove(index);
            return;
        }
    }

    ArrayList<StatusBarNotification> notificationsForPackage(String packageName) {
        ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>();
        int N = mOngoing.size();
        for (int i=0; i<N; i++) {
            if (matchPackage(mOngoing.get(i), packageName)) {
                list.add(mOngoing.get(i));
            }
        }
        N = mLatest.size();
        for (int i=0; i<N; i++) {
            if (matchPackage(mLatest.get(i), packageName)) {
                list.add(mLatest.get(i));
            }
        }
        return list;
    }
    
    private final boolean matchPackage(StatusBarNotification snb, String packageName) {
        if (snb.data.contentIntent != null) {
            if (snb.data.contentIntent.getTargetPackage().equals(packageName)) {
                return true;
            }
        } else if (snb.data.pkg != null && snb.data.pkg.equals(packageName)) {
            return true;
        }
        return false;
    }
    
    private static final int indexForKey(ArrayList<StatusBarNotification> list, IBinder key) {
        final int N = list.size();
        for (int i=0; i<N; i++) {
            if (list.get(i).key == key) {
                return i;
            }
        }
        return -1;
    }

    StatusBarNotification get(IBinder key) {
        int index;
        index = indexForKey(mOngoing, key);
        if (index >= 0) {
            return mOngoing.get(index);
        }
        index = indexForKey(mLatest, key);
        if (index >= 0) {
            return mLatest.get(index);
        }
        return null;
    }

    // gets the index of the notification's view in its expanded parent view
    int getExpandedIndex(StatusBarNotification notification) {
        ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest;
        final IBinder key = notification.key;
        int index = 0;
        // (the view order is backwards from this list order)
        for (int i=list.size()-1; i>=0; i--) {
            StatusBarNotification item = list.get(i);
            if (item.key == key) {
                return index;
            }
            if (item.view != null) {
                index++;
            }
        }
        Slog.e(StatusBarService.TAG, "Couldn't find notification in NotificationViewList.");
        Slog.e(StatusBarService.TAG, "notification=" + notification);
        dump(notification);
        return 0;
    }

    void clearViews() {
        int N = mOngoing.size();
        for (int i=0; i<N; i++) {
            mOngoing.get(i).view = null;
        }
        N = mLatest.size();
        for (int i=0; i<N; i++) {
            mLatest.get(i).view = null;
        }
    }
    
    int ongoingCount() {
        return mOngoing.size();
    }

    int latestCount() {
        return mLatest.size();
    }

    StatusBarNotification getOngoing(int index) {
        return mOngoing.get(index);
    }

    StatusBarNotification getLatest(int index) {
        return mLatest.get(index);
    }

    int size() {
        return mOngoing.size() + mLatest.size();
    }

    void add(StatusBarNotification notification) {
        if (StatusBarService.SPEW) {
            Slog.d(StatusBarService.TAG, "before add NotificationViewList"
                    + " notification.data.ongoingEvent=" + notification.data.ongoingEvent);
            dump(notification);
        }

        ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest;
        long when = notification.data.when;
        final int N = list.size();
        int index = N;
        for (int i=0; i<N; i++) {
            StatusBarNotification that = list.get(i);
            if (that.data.when > when) {
                index = i;
                break;
            }
        }
        list.add(index, notification);

        if (StatusBarService.SPEW) {
            Slog.d(StatusBarService.TAG, "after add NotificationViewList index=" + index);
            dump(notification);
        }
    }

    void dump(StatusBarNotification notification) {
        if (StatusBarService.SPEW) {
            boolean showTime = false;
            String s = "";
            for (int i=0; i<mOngoing.size(); i++) {
                StatusBarNotification that = mOngoing.get(i);
                if (that.key == notification.key) {
                    s += "[";
                }
                if (showTime) {
                    s += that.data.when;
                } else {
                    s += that.data.pkg + "/" + that.data.id + "/" + that.view;
                }
                if (that.key == notification.key) {
                    s += "]";
                }
                s += " ";
            }
            Slog.d(StatusBarService.TAG, "NotificationViewList ongoing: " + s);

            s = "";
            for (int i=0; i<mLatest.size(); i++) {
                StatusBarNotification that = mLatest.get(i);
                if (that.key == notification.key) {
                    s += "[";
                }
                if (showTime) {
                    s += that.data.when;
                } else {
                    s += that.data.pkg + "/" + that.data.id + "/" + that.view;
                }
                if (that.key == notification.key) {
                    s += "]";
                }
                s += " ";
            }
            Slog.d(StatusBarService.TAG, "NotificationViewList latest:  " + s);
        }
    }

    StatusBarNotification get(View view) {
        int N = mOngoing.size();
        for (int i=0; i<N; i++) {
            StatusBarNotification notification = mOngoing.get(i);
            View v = notification.view;
            if (v == view) {
                return notification;
            }
        }
        N = mLatest.size();
        for (int i=0; i<N; i++) {
            StatusBarNotification notification = mLatest.get(i);
            View v = notification.view;
            if (v == view) {
                return notification;
            }
        }
        return null;
    }

    void update(StatusBarNotification notification) {
        remove(notification);
        add(notification);
    }

    boolean hasClearableItems() {
        int N = mLatest.size();
        for (int i=0; i<N; i++) {
            if (mLatest.get(i).data.clearable) {
                return true;
            }
        }
        return false;
    }
}
