/*
File: Singleton.js

This function will transform any given function into singleton pattern

License:
  MIT-style license.

Author:
  Takashi Mizohata <beatak@nydd.org>

Copyright:
  2008 [nydd](http://code.nydd.org/).
*/

/*
Function: Singleton

This function will transform any given function into singleton pattern

Arguments:
  str - (String) Very important! You have to pass a name of the object by string

Return:
  (Object)

Examples:
>  var Foo = function () {...}
>  Foo.prototype.bar = function () {...}
>  Foo = Singleton('Foo');
>  var a = Foo.getInstance(); // ok!
>  var b = new Foo() // -> raise an error
*/
var Singleton = function (str)
{
  var arr = str.split('.');
  var original = window[arr.shift()];
  while (arr.length > 0)
  {
    original = accessor[arr.shift()]
  }
  var constructor = original.prototype.constructor;
  original.prototype.__initInstance = function ()
  {
    delete original.prototype.__initInstance;
    constructor.apply(this, arguments);
  }

  eval(str + ' = function(){throw new Error("This adopts a singleton pattern. Please use getInstance() instead.");};');
  arr = str.split('.');
  var singleton = window[arr.shift()];
  while (arr.length > 0)
  {
    singleton = singleton[arr.shift()]
  }

  singleton.getInstance = function ()
  {
    (singleton.initObject).apply(singleton, arguments);
    return singleton.getInstance();
  }

  singleton.initObject = function ()
  {
    delete singleton.initObject;
    var arg = arguments;
    var InnerClass = function () {
      (this.__initInstance).apply(this, arg);
    }
    InnerClass.prototype = original.prototype;
    var instance = new InnerClass();
    singleton.getInstance = function ()
    {
      return instance;
    }
  }
  eval(str + ' = null;');

  for (var i in original)
  {
    if (i !== 'prototype')
    {
      singleton[i] = original[i];
    }
  }

  return singleton;
}

