
var GenericButton = Class.create({
	initialize: function (element, options) {
		this.element = $(element);
		if (!this.element) return;
		this.options = Object.extend({
		}, options || {});
		var self = this;
		$H(this.options).each( function (opt) {
			self.element.observe(opt.key, opt.value);
		});
		return this.element;
	}
	
});

var ViewBagButton = Class.create( GenericButton, {
	initialize: function ($super, element, options) {
		this.element = $(element);
		this.options = Object.extend({
			click: function (evt) {
				if (transaction.hasCartItems) {
					document.location.href = '/checkout/viewcart.tmpl';
					evt.stop();
				} else {
					evt.stop();
				}
			}			
		}, options || {});
		return $super(this.element, this.options);	
	}
});

var SignoutButton = Class.create( GenericButton, {
	initialize: function ($super, element, options) {
		this.element = $(element);
		this.options = Object.extend({
			click: function (evt) {
				evt.stop();
				// logout under the covers
				new Ajax.Request('/rpc/account/signout.tmpl',{
					onSuccess: function () { 
						var currentUrl = location.href;
						// redirect - insecure - this host
						location.href = 'http://'+currentUrl.parseUri().host; 
						},
					onFailure: function () { alert('There was an error, you were not logged out.') }
				});
			}			
		}, options || {});
		return $super(this.element, this.options);	
	}
});

var ForgotPWLink = Class.create(GenericButton, {
    state: 'Ready',
    initialize: function($super, element, options) {
        this.element = $(element);
        if (this.element) {
            this.form = this.element.up('form');
            this.email = this.form['EMAIL_ADDRESS'];
            if ( this.email ) {
                this.email = $(this.email);
                var emid = this.email.id;
                
                // Try to find the corresponding label
                var lbl = $(this.email).up().select('[for="'+emid+'"]');
                if ( lbl && lbl[0] )
                    this.emlbl = $(lbl[0]);
            }
            
            this.options = Object.extend({
                click: function(evt) {
					this.form.__Validation.reset();
                    if (this.email.value != '' && Validation.test('validate-email', this.email)) {
                        // if ( this.email ) this.email.removeClassName('error');
                        // if ( this.emlbl ) this.emlbl.removeClassName('error');
                        jsonRpcWrapper.fetch({
                            method: 'user.emailAvailable',
                            params: [{
                                "EMAIL_ADDRESS": this.email.value
                            }],
                            onSuccess: function(t) {
								/*
							    # -1: ACCOUNT ALREADY EXISTS AS OPTIN
								# 0: ACCOUNT ALREADY EXISTS
							    # 1: ACCOUNT IS AVAILABLE								
								*/	
                                if (t.getValue() == 0) {
                                    // this email is valid
                                    var host = location.href.parseUri().host;
                                    new HiddenForm({
                                        action: 'https://' + host + '/account/password_request.tmpl',
                                        method: 'post'
                                    }).elements({
                                        EMAIL_ADDRESS: this.email.value
                                    }).submit();
                                } else {
                                    // we dont know this user ..
									this.form.__MM.showMessage( 'signin_error', this.email );									
                                }
                            }.bind(this),
                            onError: function() {
								this.form.__MM.showMessage( 'signin_error', this.email );
                            }.bind(this)
                        });
                    } else {
                        if (this.email.value == '') {
							// no email
							this.form.__MM.showMessage( 'password_hint_email_required', this.email );
                            if ( this.email ) this.email.addClassName('error');
                            if ( this.emlbl ) this.emlbl.addClassName('error');
                        } else {
							// incorrect formatting
							this.form.__MM.showMessage( 'requiredor-email_address_device_id', this.email );
                        }
                    }
                    evt.stop();
                }.bind(this)
            },
            options || {});

            return $super(this.element, this.options);
        } else {
            return null;
        }
    }
});

var cartButton = function(args) {
    var btnObj = {};
    var _initProgress = function(btn) {
        if ($(btn.progressNode) && $(btn.domNode)) {
			btn.progress = new Progress({
				"progressNode": btn.progressNode, 
				"containerNode": btn.domNode
			});
		}
    };
    
    var _initEvent = function(btn) {
        if ($(btn.domNode)) {
            Event.observe(btn.domNode, 'click', function(evt) {
                _onClick(btn);
                evt.preventDefault();
            });
        }
    };
        
    var _onClick = function(btn) {
        if (btn.progress) {
            btn.progress.start();
        }
        var cart_id = transaction[btn.cartMethod](
            btn.cartArgs,
            {
    			success: function ( t ) {
    			    if (btn.progress) {
    					btn.progress.revert();
    				}
    				console.log( "success " + t );
    				btn.onSuccess();
    			},
    			failure: function ( t ) { 
    			    if (btn.progress) {
    					btn.progress.revert();
    				}
    				console.log( "failure " + t );
    				btn.onFailure();
    			}
    		}
        );
    };
    var defaultArgs = {
        domNode: null,   
    	progressNode: null,
        progress: null,
        onSuccess: function() {},
        onFailure: function() {},
        cartMethod: "",
        cartArgs: {}
    };
    Object.extend(btnObj, defaultArgs);
    Object.extend(btnObj, args || {});
    _initProgress(btnObj);
    _initEvent(btnObj);    
    btnObj.setCartMethod = function(m) {
        if (typeof m === 'string' && m.length > 0) {
            this.cartMethod = m;
        }
    };
    btnObj.setCartArgs = function(mArgs) {
        Object.extend(this.cartArgs, mArgs || {});
    };
    return btnObj;
};

var addButton = function(args) {
    defaultArgs = {
        "domNode" : "",
        "progressNode" : "",
        cartMethod: 'add',
        cartArgs: {
            "cart_id" : "",
            "sku_id" : "",
            "sku_base_id" : "",
            "shopping_id" : "",
            "collection_id" : "",
            "increment" : true,		
            "qty" : 1
        }
    };
    Object.extend(defaultArgs, args || {});
    var btnObj = cartButton(defaultArgs);
    btnObj.setShoppable = function(shoppable) {
        if (!shoppable) {
            btnObj.domNode.hide();
        } else {
            btnObj.domNode.show();            
        }
    };
    return btnObj;
};
 
var removeButton = function(args) {
    defaultArgs = {
        "domNode" : "",
        "progressNode" : "",
        cartMethod: 'remove',
        cartArgs: {
            "cart_id" : "",
            "sku_id" : "",
            "sku_base_id" : "",
            "collection_id": ""
        }
    };
    Object.extend(defaultArgs, args || {});
    var btnObj = cartButton(defaultArgs);
    return btnObj;
};

// This class makes a link a "print" button.
// To use, pass the link as the first parameter, then include the div (or element) to print
// as an option.  For example, if you have a link defined as:
//	<a href="#" id="myPrintButton">print</a>
// and this link should print the content in this div:
//	<div id="divWithContent">blah...</div>
// Then all you need to do is:
//	new PrintButton ( $('myPrintButton'), { divToPrint: $('divWithContent') } );
//
// This works by creating a temp div off of the body, copying the contents 
// to print into that div, and then setting all elements except that div
// to "display:none" via the css styles ".noprint" and ".printable".
// (These styles are in cl_global.css.)
var PrintButton = Class.create ( GenericButton, {
	divToPrint: null,
	tmpDivId: 'temp_print_div_body',
	
	initialize: function ($super, element, options) {
		this.element = $(element);
		this.divToPrint = options['divToPrint'];
		delete options['divToPrint'];
		
		this.options = Object.extend({
			click: function (evt) {
				this.doPrint();
				evt.stop();
			}.bind(this)
		}, options || {});
		return $super(this.element, this.options);	
	},
	
	// There are a couple of quirks in printing.
	// First, in IE6 we need to set a timeout after we copy the div content
	// and before we call window.print().  This is because IE may not have completed
	// rendering the content due to event queue timing.  
	// Then, after the window.print() returns, the spooler may still be
	// reading the window content.  Therefore, we can't immediately restore
	// the page content (by hiding the temp div and removing the ".noprint" class
	// from the page elements).  Thus, we just make the temp div clickable, 
	// and when the user clicks the tmp div we restore the page.  (In cl_global.css,
	// the ".printable" class, we define a background image, that in our case says
	// "click here when printing is done".)
	
	// Main function to start the printing.
	doPrint: function() {
		// Make sure the tmp div exists.
		if (!$(this.tmpDivId)) {
			$(document.body).insert(
				{
					top : '<div id="' + this.tmpDivId + '"></div>'
				});
		}
		
		// Set the printable style and copy over the content
		$(this.tmpDivId).addClassName('printable');
		$(this.tmpDivId).innerHTML = this.divToPrint.innerHTML;
		
		// Set the noprint style on all other elements
		$(document.body).childElements().each( 
			function(el) {
				if ( el.id != this.tmpDivId ) {
					el.addClassName('noprint');
				}
			}
		);
		
		// Set up our "done printing" click event
		$(this.tmpDivId).observe('click', function(evt) { this.doPrintend(); }.bind(this) );
		
		// Set up the timeout to bring up the print dialog
		setTimeout ( this.doPrintstart.bind(this), 200 );
	},
	
	doPrintstart: function() {
		// Show the print dialog
		window.print();
	},
	
	// This function is called when user clicks on the tmp div.
	// Assume printing is done, so restore page.
	doPrintend: function() {
		
		// Remove the noprint class
		$(document.body).childElements().each( 
			function(el) {
				if ( el.id != this.tmpDivId ) {
					el.removeClassName('noprint');
				}
			}
		);
		
		// Hide the tmp div
		$(this.tmpDivId).removeClassName('printable');
		$(this.tmpDivId).addClassName('noprint');
	}
	
});

var PageLinkButton = Class.create( GenericButton, {
	initialize: function ($super, element, options) {
		if ( element ) {
			this.element = $(element);
			if ( options['hrefRedir'] ) {
				this.element.hrefRedir = options['hrefRedir'];
				delete options['hrefRedir'];
			} else {
				this.element.hrefRedir = '#';
			}
			this.options = Object.extend({
				click: function (evt) {
					var element = Event.element(evt);
					document.location.href = element.hrefRedir;
					evt.stop();
				}			
			}, options || {});
		}
		return $super(this.element, this.options);	
	}
});

// This will be a "view order" button, which is a link on a list of orders.
// When user clicks the link, it should show the lighter window and
// call the ajax updater to reload the page with that order info.
var ViewOrderButton = Class.create ( GenericButton, {
	updater: null,
	url: '',
	orderId: 0,
	
	initialize: function ($super, element, options) {
		this.element = $(element);
		this.element.orderId = $(element).readAttribute('orderId');
		this.element.url = '/templates/includes/user/account/order_detail_window.tmpl?orderid=' + this.element.orderId;
		
		this.options = Object.extend({
			click: function (evt) {
				var element = Event.element(evt);
				if ( element.updater ) {
					element.updater.show();
				} else {
					element.updater = new LighterboxUpdater ( { 
							openButton: element,
							contentDiv: 'lighterbox-order-' + element.orderId,
							url: element.url 
							} );
				}
				evt.stop();
			}
		}, options || {});
		return $super(this.element, this.options);	
	}
});

// Generic popup window.  Just give it a url and it'll do the lighterbox thing.
var PopupButton = Class.create ( GenericButton, {
	initialize: function ($super, element, options) {
		this.element = $(element);
		this.element.url = options['url'];
		this.element.popupID = options['popupID'] || 'elm_' + generateGuid();
		
		this.element.lbargs = Object.extend({ 
			openButton: this.element,
			contentDiv: 'lighterbox-popup-' + this.element.popupID,
			url: this.element.url,
			showNow: false
			}, options);
		
		// Preload the stuff (note we set "showNow" to false above)
		this.element.updater = new LighterboxUpdater ( element.lbargs );
		
		this.options = Object.extend({
			click: function (evt) {
				var element = Event.element(evt);
				if ( element.updater ) {
					element.updater.show();
				} else {
					element.updater = new LighterboxUpdater ( element.lbargs );
				}
				evt.stop();
			}
		}, options || {});
		return $super(this.element, this.options);	
	}
});
