/* Commission View */
Commission.prototype = {
  
  form: '#commissions_form',
  form_wrapper: '#commissions_form_wrapper',
  container: '#commissions_container',  
  amount_container: '.amount_container',
  amount_input: '#commissions_form input[name="amount"]',
  amount_input_items: '#commissions_form input[name="amount_items"]',
  inputs: '#commissions_form input[type="checkbox"], #commissions_form input[type="radio"]',
  selected_inputs: '#commissions_form input:checked',
  
  material_container: '#materials_container',
  complexity_container: '#complexities_container',
  size_container: '#sizes_container',
  material_selected: '#commissions_form input[name="materials[]"]:checked',
  complexity_selected: '#commissions_form input[name="complexity"]:checked',
  size_selected: '#commissions_form input[name="size"]:checked',
  
  init: function() {    
    if ( !$(this.form).length || !$(this.container).length ) return;
    this.initListeners();
    this.refresh();    
  } ,
  
  initListeners: function() {
    var _this = this;
    // add click listener to inputs
    $(this.inputs).live('click',function(e){_this.refresh();});    
    // add scroll listener for container
    if ( $(this.container).offset() != null )
      $(this.container).data('base-top',$(this.container).offset().top);
    $(window).scroll(function(e){_this.moveContainer();});    
  },
  
  refresh: function() {    
    this.refresh_amount();
    this.refresh_display();    
  } ,
  
  refresh_amount: function() {    
    var $selected = $(this.selected_inputs),
        base=0, multiplier=1, total=0, add=0, m, b;
    $selected.each(function(i){
      b = parseFloat( $(this).data('base') );
      m = parseFloat( $(this).data('multiplier') );
      if ( m > 0 ) {
        base += b;
        multiplier *= m;
      } else {
        add += b;
      }
    });    
    total = Math.round(base*multiplier+add);
    $(this.amount_input_items).val( total );
    // check for coupon
    if ( _coupon.coupon ) {
      total = _coupon.calculate_amount( total, _coupon.coupon );
    }
    $(this.amount_container).text( total );
    $(this.amount_input).val( total );    
  },
  
  refresh_display: function() {
    this.refresh_checkbox(this.material_container,this.material_selected);
    this.refresh_radio(this.size_container,this.size_selected);
    this.refresh_radio(this.complexity_container,this.complexity_selected);
  },

  refresh_checkbox: function( container, selected ) {
    var container = $(container), $selected = $(selected),
        unames='', current_unames = container.data('current');    
    $selected.each(function(i){
      unames += $(this).data('uname') + ' ';
    });
    $.trim( unames );    
    container.removeClass(current_unames);
    container.addClass(unames);
    container.data('current',unames);
  },
  
  refresh_radio: function( container, selected ) {
    var $container = $(container), $selected = $(selected).first(),
        uname = $selected.data('uname'), current_uname = $container.data('current');
    $container.removeClass(current_uname);
    $container.addClass(uname);
    $container.data('current',uname);
  },
  
  moveContainer: function() {    
    var scroll_amount = parseInt( $(window).scrollTop() ),
        base_amount = parseInt( $(this.container).data('base-top') ),
        combined_amount = scroll_amount+base_amount,
        max = $(this.form_wrapper).height();         
    if ( scroll_amount > base_amount && combined_amount < max ) {
      $(this.container).css({'position':'fixed','top':0});
    } else {
      $(this.container).css('position','relative');
    }
  }
  
}

function Commission(){}
var _commission = new Commission();

/* Coupon */
Coupon.prototype = {
  
  coupon_apply_buttons: '.coupon_apply',
  coupon_input: 'input[name="coupon_code"]',
  amount_input: 'input[name="amount"]', // amount after discount
  amount_input_items: 'input[name="amount_items"]', // amount before discount
  amount_containers: '.amount_container',
  
  coupon: null,
  
  init: function() {
    
    if ( !$(this.amount_input).length || !$(this.amount_input_items).length ) return;
    
    // initialize
    this.init_buttons();
     
  },
  
  init_buttons: function() {
    var _this = this;
    // retrieve coupon when user clicks 'apply'
    $(this.coupon_apply_buttons).live('click', function(e) {
      e.preventDefault();
      _this.set( );
    });
  },
  
  set: function( ) {
    var _this = this, coupon_code = $(this.coupon_input).first().val() || '';
    this.before_set();
    // retrieve coupon
    $.ajax({
      url: '/coupons/set',
      data: { 'coupon_code': coupon_code, 'format': 'json' },
      success: function(data){
        var response = eval("(" + data + ")");
        _this.after_set( response ); 
      }
    });
  },
  
  before_set: function() {    
    var $buttons = $(this.coupon_apply_buttons);    
    // update button text
    $buttons.each(function(){
      $(this).data('original',$(this).text());
      $(this).text('applying coupon...');
    });    
  },
  
  after_set: function(response) {
    var $buttons = $(this.coupon_apply_buttons), 
        amount = $(this.amount_input_items).first().val() || 0, amount_discounted; 
    // coupon success
    if ( response.coupon ) {
      this.coupon = response.coupon;
      // update amount containers
      amount_discounted = this.calculate_amount( amount, this.coupon );
      this.update_amounts( amount_discounted );
      alert('Coupon ('+this.coupon.discount_description+') has been successfully applied!');
    // coupon fail
    } else {
      alert('Coupon code is invalid or expired!');
    }
    // update button text
    $buttons.each(function(){
      $(this).text($(this).data('original'));
    });
  },
  
  update_amounts: function( amount ) {
    $(this.amount_containers).text( amount );
    $(this.amount_input).val( amount );
    $(this.amount_containers).effect("highlight", {}, 3000);
  },
  
  calculate_amount: function( amount_original, coupon ) {
    var amount = 0, c_amount_fixed = parseFloat(coupon.amount_fixed),
        c_discount_amount = parseFloat(coupon.discount_amount),
        c_discount_percent = parseInt(coupon.discount_percent);
    amount_original = parseFloat(amount_original);
    if ( isNaN(amount_original) ) return 0;
    if ( ! coupon ) return amount_original;
    if ( c_amount_fixed > 0 && amount_original > c_amount_fixed ) {
      amount = _util.round( c_amount_fixed, 2 );
    } else {
      amount = _util.round( amount_original-amount_original*c_discount_percent/100-c_discount_amount, 2 );
    }
    if ( amount < 0 ) return 0;
    return amount;    
  }
  
}

function Coupon(){}
var _coupon = new Coupon();

/* Form Util */
FormUtil.prototype = {
  
  submitButton : ':submit',
  successDiv : '.validation-success',
  errorDiv : '.validation-error',
  imageDiv : 'form .image-placeholder',
  imageInput : '.image-input',
  defaultErrorMessage : 'There was an error with your submission, please check your input for errors',
  
  init: function() {
    this.initAjaxForm();
    this.initAjaxUpload();
    this.initPlaceholders();
  } ,
  
  initAjaxForm: function() {
    var _this = this;
    $('form[data-remote="true"]').bind('submit', function(e) {
      e.preventDefault();
      _this.submitAjaxForm( $(this) );
    });
  },
  
  initAjaxUpload: function() {
    var _this = this;
    $('input[type=file]').live('change',function() {
      var url = $(this).data('url') + '?format=json' ,
        $form = $(this).closest('form');
      _this.fileAjaxBefore( $form );
      $(this).upload(url, function(res) {
        _this.fileAjaxSuccess( res, $form );
      }, 'json');
    });
  },
  
  initPlaceholders: function() {
    $('input[data-placeholder], textarea[data-placeholder]').each(function(){
      var value = $(this).val(), placeholder = $(this).data('placeholder');
      if ( value=='' ) $(this).val(placeholder);
    });
    $('input[data-placeholder], textarea[data-placeholder]').live('focus', function(e){
      var value = $(this).val(), placeholder = $(this).data('placeholder');
      if ( value==placeholder ) $(this).val('');
    });
    $('input[data-placeholder], textarea[data-placeholder]').live('blur', function(e){
      var value = $(this).val(), placeholder = $(this).data('placeholder');
      if ( value=='' ) $(this).val(placeholder);
    });    
  },
  
  submitAjaxForm: function($form) {
    var _this = this, url = $form.attr('action') + '?format=json', form_data = this.getData( $form );
    $form.ajaxSubmit({
      url: url,
      beforeSubmit: _this.ajaxBefore,
      success: _this.ajaxSuccess,
      dataType: 'json',
      data: form_data
    });
  },
  
  getData: function( $form ) {
    var data = {};
    if ( image_data = this.getImageData($form) ) {
      data.image_data = image_data;
    }
    return data;
  },
  
  ajaxBefore: function( data, form, options ) {    
    var $form = $(form);
    _form.disableSubmit( $form );
    _form.hideSuccess( $form );
    _form.hideError( $form );    
  },
  
  ajaxSuccess: function( response, status, xhr, form ) {
    
    var $form = $(form), $modal=false, $scroll=false, error_message;
      
    // retrieve modal    
    if ( $form.data('modal') != undefined )
      $modal = $( $form.data('modal') );
      
    // retrieve scroll    
    if ( $form.data('scroll') != undefined )
      $scroll = $( $form.data('scroll') );
    
    // valid input
    if ( response.valid > 0 ) {         
      
      if ( response.redirect && response.message ) { // message and redirect
        _form.showSuccess( $form, response.message);
        _util.redirect( response.redirect, 1000 );      
      } else if ( response.redirect ) { // just redirect
        _util.redirect( response.redirect, 0 );      
      } else if ( response.message != "" ) { // just message
        _form.showSuccess( $form, response.message);      
      }      
      // close modal on success
      if ( $modal ) $modal.modal('hide');      
      // scroll on success
      if ( $scroll ) _util.scrollToTarget( $scroll );      
      // update page with data
      if ( response.create_object != undefined ) {
        _form.createObject( $form, response.create_object );
      }
      
    // invalid input
    } else {
            
      error_message = response.message || _form.defaultErrorMessage;
      _form.showError( $form, error_message );
      _form.enableSubmit( $form );
      if ( response.redirect ) { // redirect
        _util.redirect( response.redirect, 1000 );      
      }
    }
    // enable submit
    if ( ! response.redirect ) { 
      _form.enableSubmit( $form );
    }
    
  } ,
  
  fileAjaxBefore: function( $form ) {    
    // hide submit button
    $form.find('input[type="submit"]').hide();    
  },
  
  fileAjaxSuccess: function( response, $form ) {
    
    var error_message;
    this.hideSuccess( $form );
    this.hideError( $form );
    
    if ( response.valid > 0 ) {
      
      // show submit button
      $form.find('input[type="submit"]').show();
      
      // place image
      if ( response.image != undefined ) {
        $(this.imageDiv).html('<img src="'+response.image+'" />');
      }
      if ( response.file_name != undefined ) {
        $(this.imageInput).val(response.file_name);
      }
      // show message
      if ( response.message != "" ) {
        this.showSuccess( $form, response.message);      
      }
    } else {
      // show error
      error_message = response.message || this.defaultErrorMessage;
      this.showError( $form, error_message );      
    }
    
  },
  
  disableSubmit: function( $form ) {    
    var loading_text = '',
      $button = $form.find(this.submitButton).first(),
      default_text = $button.val();
    
    // check for loading text
    if ( $button.data("loading") != undefined )
      loading_text = $button.data("loading");
    
    // disable button and show loading text
    $button.attr('disabled','disabled');
    if ( loading_text ) {
      if ( $button.data('default') == undefined )
        $button.data('default',default_text);
      $button.val(loading_text);
    }    
  },
  
  enableSubmit: function( $form ) {    
    var $button = $form.find(this.submitButton).first(),
      default_text = $button.val();
    
    // get default text
    if ( $button.data("default") != undefined )
      default_text = $button.data("default");
     
    // enable button and show default text
    $button.removeAttr("disabled");
    $button.val(default_text);    
  } ,
  
  showSuccess: function( $form, message ) {    
    this.hideError( $form );
    $form.find(this.successDiv).html( message );
    $form.find(this.successDiv).fadeIn();    
  } ,
  
  showError: function( $form, message ) {    
    this.hideSuccess( $form );
    if ( $form.find(this.errorDiv).length ) {
      $form.find(this.errorDiv).html( message );
      $form.find(this.errorDiv).fadeIn();
    } else {
      alert(message);
    }
  } ,
  
  hideSuccess: function( $form ) {
    $form.find(this.successDiv).empty();
    $form.find(this.successDiv).hide();
  } ,
  
  hideError: function( $form ) {
    $form.find(this.errorDiv).empty();
    $form.find(this.errorDiv).hide();
  } ,
  
  createObject: function( $form, object ) {
    if ( !object ) return;    
    var $template=false, $target=false;    
    // retrieve template
    if ( $form.data('template') != undefined )
      $template = $( $form.data('template') );    
    // retrieve target    
    if ( $form.data('target') != undefined )
      $target = $( $form.data('target') );
    if ( !$template || !$target ) return;
    
    var tpl = $template.html(), $clone = $template.clone( true, true );

    // iterate over object and replace values in template
    $.each( object, function(key, value) {      
      if( typeof value === 'string' || typeof value === 'number' ) {
        tpl = tpl.replace('%'+key+'%',value);
      }      
    });
    
    // remove id, set html, prepend to target, fade in, refresh plugins
    $clone.removeAttr('id');
    $clone.html( tpl );
    $clone.prependTo( $target );
    $clone.fadeIn();
    _util.pluginInit();
    
  } ,
  
  getImageData: function( $form ) {
    if ( $form.find('.image_data_source').length  ) {
      var $image_data_source = $form.find('.image_data_source').first(), image_data_url;
      $image_data_source = document.getElementById($image_data_source.attr('id'));
      image_data_url = $image_data_source.toDataURL('image/png');
      return image_data_url;
    }
    return false;
  }

}

function FormUtil(){}
var _form = new FormUtil();

/* Payment gateway */
Payment_gateway.prototype = {
  
  init: function() {
    this._initPaymentForm();
  },
  
  _initPaymentForm: function() {
    
    var _this = this;
    $('.payment-gateway-form').live('submit', function(e) {
      e.preventDefault();
      _this._submitForm( $(this) );
    });
    
  },
  
  _submitForm: function( $form ) {
    var _this = this, payment_gateway = $form.data('payment_gateway');      
    switch(payment_gateway) {
      case 'stripe':
        _this._submitStripeForm( $form );
        break;
      default:
        // submit form normally
        _form.submitAjaxForm( $form );
        break;
    }
  },
  
  _submitStripeForm: function( $form ) {
    var amount = parseFloat( $form.find('.card-amount').val() ),
        _this = this;
    // disable current form
    _form.ajaxBefore( null, $form, null );
    // create the stripe token
    Stripe.createToken({
        number: $form.find('.card-number').val(),
        cvc: $form.find('.card-cvc').val(),
        exp_month: $form.find('.card-expiry-month').val(),
        exp_year: $form.find('.card-expiry-year').val()
    }, amount, function(status, response){
      // handle response
      _this._stripeResponseHandler( $form,status,response );
    });
  },
  
  _stripeResponseHandler: function( $form, status, response ) {
    if (response.error) {
      // show the errors on the form
      _form.showError( $form, response.error.message );
      _form.enableSubmit( $form );
    } else {
      // insert token into form and submit
      var token = response['id'];
      $form.find('input[name="payment_gateway_token"]').val(token);
      _form.submitAjaxForm( $form );
    }
  }
  
}
function Payment_gateway(){}
var _payment_gateway = new Payment_gateway();

/* Util */
Util.prototype = {
  
  init: function() {
    
    var _this=this;
    
    $('.scroll').live('click', function(e){
      e.preventDefault();
      _this.scrollToTarget($(this).attr('href'));      
    });
    
    $('.toggle').live('click', function(e){
      e.preventDefault();
      var slide = $(this).hasClass('slide'),
          group = $(this).data('group');
      if ( group==undefined ) group = false;
      _this.toggle($(this).attr('href'),slide,group); 
    });
    
    $('a[data-loading]').live('click', function(e) {
      _this.linkLoadingText( $(this) );
    });
    
    $('ul.gallery').each( function(){
      _this.loadGallery( $(this) );
    });
     
  } ,
  
  redirect: function( url, timeout ) {
    if ( timeout != null && timeout > 0 ) {
      setTimeout( "window.location = '"+url+"';", timeout );
    } else {
      window.location = url;
    }
  } ,
  
  round: function( num, precision ) {
    if ( num % 1 === 0 ) {
      return num;
    }
    if ( !precision ) {
      return Math.round(num);
    }    
    return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision);    
  },
  
  linkLoadingText: function($a) {
    $a.text($a.data('loading'));
    $a.click(function () { return false; });
  } ,
  
  scrollToTarget: function(t) {
    var target_offset = $(t).offset(),
        padding_top = parseInt($('body').css('paddingTop'));
        target_top = target_offset.top - padding_top;
    $('html, body').animate({scrollTop:target_top}, 500);
  } ,
  
  toggle: function(t,slide,group) {
    var id=t.slice(1);
    if ( group )
      $('.'+group+'[id!="'+id+'"]').hide();
    if ( slide )
      $(t).slideToggle();
    else 
      $(t).fadeToggle();
  } ,
  
  getTitle: function( $el ) {
    var title = $el.attr('title'), link_title = '[Link]';
    // check for title in data from twipsy
    if ( $el.data('original-title') != undefined && $el.data('original-title') )
      title = $el.data('original-title');
    // check for link
    if ( $el.data('link') != undefined && $el.data('link') ) {          
      if ( $el.data('link-title') != undefined && $el.data('link-title') ) {
        link_title = $el.data('link-title');
      }
      title += ' <a href="'+$el.data('link')+'">'+link_title+'</a>';
    }
    return title ;
  } ,
  
  loadGallery: function ( $ul ) {
    var interval = $ul.data('interval')!=undefined ? parseInt($ul.data('interval')) : 3000;
    this.stepGallery($ul,-1,interval);
  } ,
  
  stepGallery: function( $ul, index, interval ) {
    var _this = this, new_index = index+1, list_length = $ul.children('li').length;
    if ( new_index >= list_length ) new_index = 0;
    if ( index>-1 ) $ul.children('li').eq(index).fadeOut();
    $ul.children('li').eq(new_index).fadeIn();
    setTimeout( function(){
      _this.stepGallery( $ul, new_index, interval );
    }, interval );
  }
  
}

function Util(){}
var _util = new Util();

$(document).ready(function(){  
  
  _commission.init();
  _coupon.init();
  _form.init();
  _payment_gateway.init();
  _util.init();  

});

