Ext.ux.CartActions = function(opts) {
  this.addEvents(
    'beforeRemove',
    'remove', 
    
    'beforeAdd',
    'add', 
    
    'beforeClear',
    'clear',
    
    'beforeCheckout',
    'checkout',

    'refresh',
    'view'
  );
  
  Ext.ux.CartActions.superclass.constructor.call(this);
};
        
Ext.extend(Ext.ux.CartActions, Ext.util.Observable, {
  checkout: function() {
    this.fireEvent('beforeCheckout');
    this.fireEvent('checkout');
  },
  
  clear: function() {
    ExtApp.submit({
      url: '/cart/clear',
      method: 'POST',
      confirm: 'Are you sure you wish to clear your cart?',
      listeners: {
        scope: this,
        beforerequest: function() {
          this.fireEvent('beforeClear');
        },
        complete: function(xhr, opts, results) {
          this.fireEvent('clear', results);
        }
      }
    });
  },
  
  remove: function(type, id) {
    this.fireEvent('beforeRemove', type, id);
    
    ExtApp.submit({
      url: '/cart/remove',
      params: { type: type, id: id },
      method: 'POST',
      listeners: {
        scope: this,
        complete: function(xhr, opts, results) {
          this.fireEvent('remove', results);
        }
      }
    });
  }, 
  
  add: function(type, id) {
    this.fireEvent('beforeAdd', type, id);
    
    ExtApp.submit({
      url: '/cart/add',
      params: { type: type, id: id },
      method: 'POST',
      listeners: {
        scope: this,
        complete: function(xhr, opts, results) {
          this.fireEvent('add', results);
        }
      }
    });
  },

  refresh: function() {
    this.fireEvent('refresh');
  },

  view: function(type, id) {
    this.fireEvent('view', type, id);
  },

  save: function() {
    Ext.Msg.prompt('Save Cart as...', 'Please enter a name for this cart:', function(button, text) {
      if (button == 'ok') {
        ExtApp.submit({
          url: '/carts',
          params: { name: text },
          method: 'PUT'
        });
      }
    });
  },

  find_cart: function(cart) {
    var win = Ext.getCmp('saved-cart-window');
    if(!win) {
      var cart_grid = new Ext.grid.GridPanel({
        loadMask: { msg: 'Fetching Saved Carts' },
        store: new Ext.data.JsonStore({
          autoLoad: true,
          url: '/cart/all',
          fields: ['id', 'name', 'size', 'count', { name: 'updated_at', type: 'date' }]
        }),
        columns: [{
          id: 'name',
          header: 'Name',
          dataIndex: 'name'
        }, {
          header: '# Items',
          width: 50,
          dataIndex: 'count'
        }, {
          header: 'Download Size',
          dataIndex: 'size',
          width: 80,
          renderer: Ext.util.Format.fileSize
        }, {
          header: 'Last Updated',
          dataIndex: 'updated_at'
        }],
        sm: new Ext.grid.RowSelectionModel({singleSelect: true}),
        viewConfig: { forceFit: true },
        autoExpandColumn: 'name',
        listeners: {
          rowclick: function(grid, rowIndex, e) {
            grid.ctxRecord = grid.getSelectionModel().getSelected();
          }
        }
      });
      win = new Ext.Window({
        id: 'saved-cart-window',
        title: 'Saved Carts',
        layout: 'fit',
        modal: true,
        width: 400,
        height: 400,
        buttons: [{
          text: 'Cancel',
          handler: function() {
            this.ownerCt.ownerCt.close();
          }
        }, {
          text: 'Load Selected Cart',
          handler: function() {
            if (!cart_grid.ctxRecord) {
              ExtApp.Notice.show({ msg: 'Please select a cart to load' });
              return false;  
            }
            this.ownerCt.ownerCt.close();
            ExtApp.submit({
              url: '/cart/load',
              method: 'POST',
              params: { id: cart_grid.ctxRecord.get('id') },
              listeners: {
                scope: this.ownerCt.ownerCt,
                success: function() {
                  cart.actions.refresh();
                }
              }
            });
          }
        }],
        items: [cart_grid]
      });
    }
    win.show();
  },

  start_fetch: function(store) {
    this.progress_task = {
      scope: this,
      run: function() {
        store.load();
      },
      interval: 10000
    }
    Ext.TaskMgr.start(this.progress_task);
  },

  stop_fetch: function() {
    if (this.progress_task) {
      Ext.TaskMgr.stop(this.progress_task);
      this.progress_task = null;
    }
  },

  download_windows: new Ext.util.MixedCollection(),
  download_scene: function(scene) {
    var win = this.download_windows.get(scene);
    if(!win) {
      win = new Ext.ux.PBarWindow({
        title: 'Retrieving scene: ' + scene,
        collapsible: true
      });
      win.start({
        url: "/scrap/fetch/" + scene
      });
      win.on('beforedestroy', function() { this.download_windows.remove(win); }, this);
    }
    win.show();
  }
});

Ext.ux.Cart = Ext.extend(Ext.grid.GridPanel, {
  initComponent: function(config) {
    if(!this.actions) {
      this.actions = new Ext.ux.CartActions();
      
      this.actions.on('beforeRemove', function(type, id) {
        this.getEl().mask('Removing item from cart', 'x-mask-loading'); 
      }, this);
      
      this.actions.on('remove', function(results) {
        if(results.success) {
          this.store.remove(
            this.store.getAt(this.store.find('name', results.id))
          );
        }
        if(results.message) { ExtApp.Notice.show({ msg: results.message }); }
        this.getEl().unmask();
      }, this);

      this.actions.on('refresh', function(results) {
        this.getStore().load();
      }, this);
          
      this.actions.on('beforeClear', function() {
        this.getEl().mask('Clearing Cart', 'x-mask-loading');
      }, this);
          
      this.actions.on('clear', function(results) {
        if(results.success) { this.getStore().removeAll(); }
        if(results.message) { ExtApp.Notice.show({ msg: results.message }); }
        this.getEl().unmask();
      }, this);
    }

    Ext.applyIf(this.store, {
      fields: [
        { name: 'id' },
        { name: 'preview' },
        { name: 'type' },
        { name: 'name' },
        { name: 'size' }
      ]
    });
    this.store = new Ext.data.JsonStore(this.store);

    Ext.apply(this, {
      loadMask: { msg: 'Loading Cart Items' },
      viewConfig: { autoFill: true, forcefit: true, scrollOffset:19 },
      autoExpandColumn: 'name',
      tbar: new Ext.Toolbar({
        items: [{
          text: 'Cart',
          icon: '/images/icons/small/package.png?1320970935',
          menu: [{
            text: 'Save',
            scope: this,
            icon: '/images/icons/small/filesave.png?1320970935',
            handler: function() {
              this.actions.save();
            }
          }, {
            text: 'Load',
            scope: this,
            icon: '/images/icons/small/fileopen.png?1320970935',
            handler: function() {
              this.actions.find_cart(this);
            }
          }, {
            text: 'Clear',
            scope: this,
            icon: '/images/icons/small/delete.png?1320970935',
            handler: function() {
              this.actions.clear();
            }
          }]
        }, '-', {
          text: 'Refresh',
          scope: this,
          icon: '/images/icons/small/reload.png?1320970935',
          handler: function() {
            this.actions.refresh();
          }
        }, '-', {
          text: 'View Selected',
          scope: this,
          handler: function() {
            var record = this.getSelectionModel().getSelected();
            if (record) {
              this.actions.view(record.get('type'), record.get('name'));
            }
          }
        }, '-', {
          text: 'Remove Selected',
          scope: this,
          icon: '/images/icons/small/button_cancel.png?1320970935',
          handler: function() {
            var record = this.getSelectionModel().getSelected();
            if (record) {
              this.actions.remove(record.get('type'), record.get('name'));
            }
          }        
        }, '->', {
          text: 'Download >>',
          scope: this,
          icon: '/images/icons/small/download.png?1320970935',
          handler: function() { 
            this.actions.checkout();
          }
        }]
      }),
      columns: [{ 
        header: 'Preview', 
        width: 110, 
        sortable: false, 
        dataIndex: 'preview',
        renderer: function(url) {
          if (!url) { url = "/images/no_preview.png"; }
          return '<img border="0" src="'+url+'" width="100" height="100" />'
        }
      }, { 
        id: 'name', 
        header: 'Name', 
        width: 300, 
        sortable: true,
        dataIndex: 'name' 
      }, { 
        header: 'Filesize', 
        width: 100, 
        sortable: true,
        dataIndex: 'size',
        renderer: Ext.util.Format.fileSize
      }]
    });
    
    Ext.ux.Cart.superclass.initComponent.call(this);
  }
});
