#ifndef H_LocalObjectTable
#define H_LocalObjectTable
/*
 * Copyright 2008 Google Inc.
 * 
 * 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.
 */

#include <vector>
#include <algorithm>

#include "Debug.h"

#include "mozincludes.h"

class LocalObjectTable {
private:
  static const int INITIAL_OBJECT_TABLE_SIZE = 300;

  int nextFree;
  std::vector<NPObject*> objects;
  bool dontFree;

  bool isFree(int id) {
    // low bit is set for free pointers, object pointers can't be odd
    NPObject* obj = objects[id];
    return !obj || (reinterpret_cast<long long>(obj) & 1);
  }

  void setFree(int id) {
    objects[id] = reinterpret_cast<NPObject*>((nextFree << 1) | 1LL);
    nextFree = id;
  }
public:
  LocalObjectTable() {
    nextFree = -1;
    objects.reserve(INITIAL_OBJECT_TABLE_SIZE);
    dontFree = false;
  }

  virtual ~LocalObjectTable();

  int add(NPObject* obj) {
    int id = find(obj);
    if (id >= 0) {
      Debug::log(Debug::Spam) << "LocalObjectTable::add(obj=" << obj
          << "): returning old id=" << id << Debug::flush;
      return id;
    }
    if (nextFree >= 0) {
      id = nextFree;
      nextFree = int(reinterpret_cast<long long>(objects[nextFree])) >> 1;
      objects[id] = obj;
    } else {
      id = static_cast<int>(objects.size());
      objects.push_back(obj);
    }
    Debug::log(Debug::Spam) << "LocalObjectTable::add(obj=" << obj << "): id=" << id
        << Debug::flush;
    // keep track that we hold a reference in the table
    NPN_RetainObject(obj);
    return id;
  }

  // TODO(jat): sublinear search
  int find(NPObject* obj) {
    std::vector<NPObject*>::iterator it = std::find(objects.begin(), objects.end(), obj);
    if (it == objects.end()) {
      return -1;
    }
    return static_cast<int>(it - objects.begin());
  }

  void free(int id) {
    Debug::log(Debug::Spam) << "LocalObjectTable::free(id=" << id << ")" << Debug::flush;
    if (unsigned(id) >= objects.size()) {
      Debug::log(Debug::Error) << "LocalObjectTable::free(id=" << id << "): invalid index (size="
          << objects.size() << Debug::flush;
      return;
    }
    if (isFree(id)) {
      Debug::log(Debug::Error) << "Freeing freed object slot " << id << Debug::flush;
      return;
    }
    NPObject* obj = objects[id];
    setFree(id);
    if (!dontFree) {
      NPN_ReleaseObject(obj);
    }
  }

  void freeAll() {
    Debug::log(Debug::Spam) << "LocalObjectTable::freeAll()" << Debug::flush;
    for (unsigned i = 0; i < objects.size(); ++i) {
      if (!isFree(i)) {
        NPObject* obj = objects[i];
        setFree(i);
        if (!dontFree) {
          NPN_ReleaseObject(obj);
        }
      }
    }
  }

  NPObject* get(int id) {
    if (unsigned(id) >= objects.size()) {
      Debug::log(Debug::Error) << "LocalObjectTable::get(id=" << id << "): invalid index (size="
          << objects.size() << Debug::flush;
      return 0;
    }
    if (isFree(id)) {
      Debug::log(Debug::Error) << "Getting freed object slot " << id << Debug::flush;
      return 0;
    }
    return objects[id];
  }

  void setDontFree(bool dontFree) {
    this->dontFree = dontFree;
  }
};

#endif
