      1 var define = require("../define").define,
      2         Collection = require("./Collection"),
      3         base = require("../base");
      4
      5 /**
      6  * @class <p>LIFO Data structure</p>
      7  * @name Stack
      8  * @augments comb.collections.Collection
      9  * @memberOf comb.collections
     10  *
     11  * @property {Number} count the current number of elements in this queue
     12  * @property {Boolean} isEmpty true if this queue is empty
     13  * @property {Array} values a copy of the values contained in this queue
     14  */
     15 module.exports = exports = define(Collection, {
     16     instance : {
     17         /**@lends comb.collections.Stack.prototype*/
     18
     19         constructor : function() {
     20             this.__stack = [];
     21             this.__next = -1;
     22         },
     23
     24         /**
     25          * Add an item to the tail of this stack
     26          * @param {*} data item to qppend to this stack
     27          *
     28          */
     29         push : function(data) {
     30             this.__stack[++this.__next] = data;
     31         },
     32
     33         /**
     34          * Removes the tail of this static
     35          * @return {*} the data at the tail of this stack
     36          */
     37         pop : function() {
     38             var ret = undefined, stack, next = this.__next;
     39             if (next >= 0) {
     40                 stack = this.__stack;
     41                 ret = stack[next];
     42                 stack[this.__next--] = undefined;
     43             }
     44             return ret;
     45         },
     46
     47         /**
     48          * Retrieves the item at the tail of the stack without removing it
     49          *
     50          * @return {*} The element at the tail of the stack. Returns undefined if the stack is empty.
     51          */
     52         peek : function() {
     53             var ret = undefined,next = this.__next;
     54             if (next >= 0) {
     55                 ret = this.__stack[next];
     56             }
     57             return ret;
     58         },
     59
     60          /**
     61          * Removes all items from this stack.
     62          */
     63         clear : function() {
     64             this.__stack.length = 0;
     65             this.__next = -1;
     66         },
     67
     68         /**
     69          * Determine if this stack contains the element
     70          * @param {*} obj the object to find
     71          *
     72          * @return {Boolean} true if this stack contains the element
     73          */
     74         contains : function(obj) {
     75             return this.__stack.indexOf(obj) != -1;
     76         },
     77
     78         /**
     79          * Removes an element from this stack.
     80          * @param {*} obj the data to remove.
     81          *
     82          * @return {Boolean} true if the element was removed, false otherwise.
     83          */
     84         remove : function(obj) {
     85             var index = this.__stack.indexOf(obj), ret = false;
     86             if (index != -1) {
     87                 if (index == this.__next) {
     88                     this.pop();
     89                 } else {
     90                     this.__stack.splice(index, 1);
     91                     this.__next--;
     92                 }
     93                 ret = true;
     94             }
     95             return ret;
     96         },
     97
     98         toString : function(){
     99             return this.__stack.toString();
    100         },
    101
    102         getters : {
    103             count : function() {
    104                 return this.__next + 1;
    105             },
    106
    107             isEmpty : function() {
    108                 return this.__next < 0;
    109             },
    110
    111             values : function() {
    112                 return this.__stack.slice(0, this.__next + 1).reverse();
    113             }
    114         }
    115     }
    116 });