define('spyl/pb/Group', ['jls/lang/Class', 'jls/lang/Exception'], function (Class, Exception) {

var Group;
Group = Class.create({
    initialize: function(name) {
        this._name = name;
        this._parent = null;
        this._items = [];
    },
    getName: function() {
        return this._name;
    },
    getParent: function() {
        return this._parent;
    },
    setParent: function(parent) {
        this._parent = parent;
    },
    addItem: function(item) {
        this._items.push(item);
    },
    getItem: function(index) {
        if ((typeof index != 'number') || (index < 0) || (index >= this._items.length)) {
            throw new Exception('Index out of bounds (' + index + ')');
        }
        return this._items[index];
    },
    getItemByName: function(name) {
        for (var i = 0; i < this.size(); i++) {
            var item = this.getItem(i);
            if (item.getName() == name) {
                return item;
            }
        }
    },
    size: function() {
        return this._items.length;
    },
    sort: function(fn) {
        return this._items.sort(fn);
    }
});

// A view contains groups that have there proper set with possible duplicates.
Group.View = Class.create(Group, {
    addItem: function($super, item) {
        $super(item);
        item.setParent(this);
    }
});

// Contains medias.
Group.Medias = Class.create(Group, {
    getPreviewMedia: function() {
        return this.getItem(0);
        //return this.getItem(Math.floor(Math.random() * this.size()));
    },
    getMedia: function(index) {
        return this.getItem(index);
    },
    getMediaCount: function() {
        return this.size();
    }
});
Group.RevertedMedias = Class.create(Group.Medias, {
    getPreviewMedia: function() {
        return this.getItem(this.size() - 1);
    },
    getMedia: function(index) {
        return this.getItem(this.size() - 1 - index);
    },
    getMediaCount: function() {
        return this.size();
    }
});

// A list contains groups that are subsets of the set of the list.
Group.List = Class.create(Group.View, {
    getPreviewMedia: function() {
        return this.getItem(0).getPreviewMedia();
        //return this.getMedia(Math.floor(Math.random() * this.getMediaCount()));
    },
    getMedia: function(index) {
        var subIndex = index;
        for (var i = 0; i < this.size(); i++) {
            var group = this.getItem(i);
            var mediaCount = group.getMediaCount();
            if (subIndex < mediaCount) {
                return group.getMedia(subIndex);
            }
            subIndex -= mediaCount;
        }
        return null;
    },
    getMediaCount: function() {
        var count = 0;
        for (var i = 0; i < this.size(); i++) {
            count += this.getItem(i).getMediaCount();
        }
        return count;
    }
});


return Group;
});
