// (c) 2009 Patrick Reiner. All rights reserved.
// version 1.0.1

// Turns an ordinary html button into a close window button.
// Note: Buttons should have style="display:none;" since they will be shown by this behavior (avoids problems for users without JS).
//
// === Applied Via
// * class "js_close_window"
//
// === Example
// * <button class="js_close_window" style="display:none;">Close This Window</button>
//
var CloseWindow = Behavior.create({
  initialize : function() {
    this.element.show()
  },
  onclick : function() {
    window.close()
  }
})
Event.addBehavior( { '.js_close_window': CloseWindow() } )

// Applies drop shadow to elements
// Note: Checks for JSRoundedCorners to properly apply shadow if corners are rounded
//
// === Applied Via
// * class "js_drop_shadow_X" --- the X specifies the shadow length of the 4 sides
//   * X can be a number, this will then be applied to all 4 sides
//   * X can be a set of 4 numbers: t_r_b_l
//
// === Example
// * <div id="page_content_frame" class="some_css_class js_drop_shadow_0_20_20_0 another_css_class">
//
var JSDropShadow = Behavior.create({
  supported_corner_radii : [ 0, 10 ],
	supported_shadow_lengths : [ 0, 8 ],
  initialize : function() {
    // Grab js_drop_shadow_X and js_rounded_corners_X (if exists) from class CSS
    rc_css_array = null
    ds_css_array = null
    all_css = this.element.readAttribute( 'class' ).split( ' ' )
    for ( var i=0; i < all_css.length; i++ ) {
      css = all_css[ i ].split( '_' ).reverse()
      t1 = css.pop()
      t2 = css.pop()
      t3 = css.pop()
      if ( t1 == 'js' && t2 == 'rounded' && t3 == 'corners' ) {
        rc_css_array = css
      }
      if ( t1 == 'js' && t2 == 'drop' && t3 == 'shadow' ) {
        ds_css_array = css
      }
    }
    
    // Determine corner radii from rc_css_array
    if ( rc_css_array !== null && rc_css_array.length == 1 ) {
      tl = tr = bl = br = parseInt( rc_css_array[ 0 ] )
    } else if ( rc_css_array !== null && rc_css_array.length == 4 ) {
      tl = parseInt( rc_css_array[ 3 ] )
      tr = parseInt( rc_css_array[ 2 ] )
      bl = parseInt( rc_css_array[ 1 ] )
      br = parseInt( rc_css_array[ 0 ] )
    } else {
      this.logFBError()
      return
    }
    
    // Determine drop shadow lengths from ds_css_array
    if ( ds_css_array.length == 1 ) {
      t = r = b = l = parseInt( ds_css_array[ 0 ] )
    } else if ( ds_css_array.length == 4 ) {
      t = parseInt( ds_css_array[ 3 ] )
      r = parseInt( ds_css_array[ 2 ] )
      b = parseInt( ds_css_array[ 1 ] )
      l = parseInt( ds_css_array[ 0 ] )
    } else {
      this.logFBError()
      return
    }
    
    // Check that all shadow and corner values are supported
    if (  this.supported_corner_radii.indexOf( tl ) == -1 ||
          this.supported_corner_radii.indexOf( tr ) == -1 ||
          this.supported_corner_radii.indexOf( bl ) == -1 ||
          this.supported_corner_radii.indexOf( br ) == -1 ||
          this.supported_shadow_lengths.indexOf( t ) == -1 ||
          this.supported_shadow_lengths.indexOf( r ) == -1 ||
          this.supported_shadow_lengths.indexOf( b ) == -1 ||
          this.supported_shadow_lengths.indexOf( l ) == -1 ) {
      this.logFBError()
      return
    }
    
    // Create shadow_container div that will contain all absolutely positioned shadow divs as well as this.element
    var shadow_container = Element.extend( document.createElement( 'div' ) )
    shadow_container.setStyle({
      position : 'relative'
    })
    // Insert this.element into shadow_container
    this.element.insert( { 'before' : shadow_container } )
    shadow_container.insert( { 'top' : this.element } )
    
    //
    // Create and insert absolutely positioned shadow divs
    //
    
    // Left
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      top : '0',
      left : '-' + l + 'px',
      width : l + 'px',
      height : '100%',
      backgroundImage : 'url(/images/js_shadows/' + l + '_l.png)',
      backgroundRepeat : 'repeat-y'
    })
    shadow_container.insert( { 'top' : image_container } )
    
    // Right
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      top : '0',
      right : '-' + r + 'px',
      width : r + 'px',
      height : '100%',
      backgroundImage : 'url(/images/js_shadows/' + r + '_r.png)',
      backgroundRepeat : 'repeat-y'
    })
    shadow_container.insert( { 'top' : image_container } )
    
    // Top Left
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      top : '-' + ( t + tl ) + 'px',
      left : '-' + t + 'px',
      width : t + tl + 'px',
      height : t + tl + 'px',
      backgroundImage : 'url(/images/js_shadows/' + t + '_' + tl + '_tl.png)',
      backgroundRepeat : 'no-repeat'
    })
    shadow_container.insert( { 'top' : image_container } )
    
    // Top
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      top : '-' + ( t + tl ) + 'px',
      left : tl + 'px',
      width : ( this.element.getDimensions().width - tl - tr ) + 'px',
      height : t + 'px',
      backgroundImage : 'url(/images/js_shadows/' + t + '_t.png)',
      backgroundRepeat : 'repeat-x'
    })
    shadow_container.insert( { 'top' : image_container } )
    
    // Top Right
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      top : '-' + ( t + tr ) + 'px',
      right : '-' + t + 'px',
      width : t + tr + 'px',
      height : t + tr + 'px',
      backgroundImage : 'url(/images/js_shadows/' + t + '_' + tr + '_tr.png)',
      backgroundRepeat : 'no-repeat'
    })
    shadow_container.insert( { 'top' : image_container } )
    
    // Bottom Left
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      bottom : '-' + ( b + bl ) + 'px',
      left : '-' + b + 'px',
      width : b + bl + 'px',
      height : b + bl + 'px',
      backgroundImage : 'url(/images/js_shadows/' + b + '_' + bl + '_bl.png)',
      backgroundRepeat : 'no-repeat'
    })
    shadow_container.insert( { 'top' : image_container } )
    
    // Bottom
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      bottom : '-' + ( b + bl ) + 'px',
      left : bl + 'px',
      width : ( this.element.getDimensions().width - bl - br ) + 'px',
      height : b + 'px',
      backgroundImage : 'url(/images/js_shadows/' + b + '_b.png)',
      backgroundRepeat : 'repeat-x'
    })
    shadow_container.insert( { 'top' : image_container } )
    
    // Bottom Right
    var image_container = Element.extend( document.createElement('div') )
    image_container.setStyle({
      position : 'absolute',
      bottom : '-' + ( b + bl ) + 'px',
      right : '-' + b + 'px',
      width : b + bl + 'px',
      height : b + bl + 'px',
      backgroundImage : 'url(/images/js_shadows/' + b + '_' + bl + '_br.png)',
      backgroundRepeat : 'no-repeat'
    })
    shadow_container.insert( { 'top' : image_container } )
  },
  logFBError : function() {
    if ( AB_GLOBALS.get( 'RAILS_ENV' ) != 'production' ) {    
      console.group( 'JSDropShadow Error' )
      console.error( 'Could not apply drop shadow to element' )
      console.log( this.element )
      console.group( 'trace' )
      console.trace()
      console.groupEnd()
      console.groupEnd()
    }
  }
})
Event.addBehavior( { 'div[class*=js_drop_shadow_]': JSDropShadow() } )

// Creates hidden larger images that are revealed when user clicks thumbnail, and hidden when user clicks larger image (instead of just linking to larger image)
//
// === Applied Via
// * class "js_enlarge_image_X" --- X is a set of two numbers that specify the size of the enlarged image in px: w_h
//
// === Example
// * <a href="/images/about_us/logistics/receiving_area.jpg" class="js_enlarge_image_480_360"><img src="/images/about_us/logistics/receiving_area.jpg" /></a>
//
var JSEnlargeImage = Behavior.create({
  initialize : function() {
    // Determine CSS
    all_css = this.element.readAttribute( 'class' ).split( ' ' )
    for ( var i=0; i < all_css.length; i++ ) {
      css = all_css[ i ].split( '_' ).reverse()
      if ( css.pop() == 'js' && css.pop() == 'enlarge' && css.pop() == 'image' ) {
        break
      }
    }
    
    // Get normal image dimensions
    if ( this.element.firstDescendant() ) {
      normal_image_dimensions = this.element.firstDescendant().getDimensions()
    } else {
      this.logFBError()
      return
    }
        
    // Determine image size from CSS
    if ( css.length == 2 ) {
      w = parseFloat( css[ 1 ] )
      h = parseFloat( css[ 0 ] )
    } else {
      this.logFBError()
      return
    }
        
    // Create larger images
    this.larger_image = Element.extend( document.createElement( 'img' ) )
    this.larger_image.hide()
    this.larger_image.setAttribute( 'src', this.element.readAttribute( 'href' ) )
    this.larger_image.setStyle({
      position : 'absolute',
      cursor : 'pointer',
      width : w + 'px',
      height : h + 'px',
      marginTop : ( ( normal_image_dimensions.height - h ) / 2 ) + 'px'
    })
    this.element.insert( { 'before' : this.larger_image } )
    
    // Create larger image behavior
    var temp_behavior = Behavior.create({
      onclick : function() {
        this.element.hide()
      }
    })
    new temp_behavior( this.larger_image )

  },
  onclick : function() {
    this.larger_image.show()
    return false
  },
  logFBError : function() {
    if ( AB_GLOBALS.get( 'RAILS_ENV' ) != 'production' ) {    
      console.group( 'JSEnlargeImage Error' )
      console.error( 'Could not apply image enlargement to link' )
      console.log( this.element )
      console.group( 'trace' )
      console.trace()
      console.groupEnd()
      console.groupEnd()
    }
  }
})
Event.addBehavior( { 'a[class*=js_enlarge_image_]': JSEnlargeImage() } )

// Applies rounded corners to div elements (see curvy_corners_lite.js for additional info and instructions)
// DIVs only due to limitation of curvyCorners
//
// === Applied Via
// * Note: if this changes, updated JSDropShadow
// * class "js_rounded_corners_X" --- the X specifies the roundedness of the 4 corners
//   * X can be a number, this will then be applied to all 4 corners
//   * X can be a set of 4 numbers: tl_tr_bl_br
//
// === Example
// * <div id="page_content_frame" class="some_css_class js_rounded_corners_0_20_20_0 another_css_class">
//
var JSRoundedCorners = Behavior.create({
  initialize : function() {
    // Grab js_rounded_corners_X from class CSS
    rc_css_array = null
    all_css = this.element.readAttribute( 'class' ).split( ' ' )
    for ( var i=0; i < all_css.length; i++ ) {
      css = all_css[ i ].split( '_' ).reverse()
      if ( css.pop() == 'js' && css.pop() == 'rounded' && css.pop() == 'corners' ) {
        rc_css_array = css
      }
    }
    
    // Determine corner radii from rc_css_array
    if ( rc_css_array.length == 1 ) {
      tl = tr = bl = br = parseInt( rc_css_array[ 0 ] )
    } else if ( rc_css_array.length == 4 ) {
      tl = parseInt( rc_css_array[ 3 ] )
      tr = parseInt( rc_css_array[ 2 ] )
      bl = parseInt( rc_css_array[ 1 ] )
      br = parseInt( rc_css_array[ 0 ] )
    } else {
      this.logFBError()
      return
    }
    
    // Set options
    settings = {
      tl: { radius: tl },
      tr: { radius: tr },
      bl: { radius: bl },
      br: { radius: br },
      antiAlias: true,
      autoPad: false
    }

    // Round corners
    var temp = new curvyCorners(settings, this.element )
    temp.applyCornersToAll()
  },
  logFBError : function() {
    if ( AB_GLOBALS.get( 'RAILS_ENV' ) != 'production' ) {    
      console.group( 'JSRoundedCorners Error' )
      console.error( 'Could not apply rounded corners to element' )
      console.log( this.element )
      console.group( 'trace' )
      console.trace()
      console.groupEnd()
      console.groupEnd()
    }
  }
})
Event.addBehavior( { 'div[class*=js_rounded_corners_]': JSRoundedCorners() } )

// Sets margin of elements (usually to offset some other JS effect that does not appear when JS is disabled)
//
// === Applied Via
// * class "js_set_margin_UOM_X" --- UOM is either 'px' or 'em' and X specifies the margin of the 4 sides.
//   * X can be a number, this will then be applied to all 4 sides
//   * X can be a set of 4 numbers: t_r_b_l (numbers can be left blank to leave that setting unchanged)
//
// === Example
// * <div id="page_content_frame" class="some_css_class js_set_margin_px_20_0__0 another_css_class">
//
var JSSetMargin = Behavior.create({
  initialize : function() {
    // Determine CSS
    all_css = this.element.readAttribute( 'class' ).split( ' ' )
    for ( var i=0; i < all_css.length; i++ ) {
      css = all_css[ i ].split( '_' ).reverse()
      if ( css.pop() == 'js' && css.pop() == 'set' && css.pop() == 'margin' ) {
        break
      }
    }
    
    // Determine unit of measure
    uom = css.pop()
    if ( uom != 'px' && uom != 'em' ) {
      this.logFBError()
      return
    }
    
    // Determine margin from CSS
    if ( css.length == 1 ) {
      t = r = b = l = parseFloat( css[ 0 ] )
    } else if ( css.length == 4 ) {
      t = parseFloat( css[ 3 ] )
      r = parseFloat( css[ 2 ] )
      b = parseFloat( css[ 1 ] )
      l = parseFloat( css[ 0 ] )
    } else {
      this.logFBError()
      return
    }
    
    // Set new margin
    this.element.setStyle({
      margin : t + uom + ' ' + r + uom + ' ' + b + uom + ' ' + l + uom
    })
  },
  logFBError : function() {
    if ( AB_GLOBALS.get( 'RAILS_ENV' ) != 'production' ) {    
      console.group( 'JSSetMargin Error' )
      console.error( 'Could not apply margin to element' )
      console.log( this.element )
      console.group( 'trace' )
      console.trace()
      console.groupEnd()
      console.groupEnd()
    }
  }
})
Event.addBehavior( { 'a[class*=js_set_margin_]': JSSetMargin() } )
Event.addBehavior( { 'div[class*=js_set_margin_]': JSSetMargin() } )

// Sets padding of elements (usually to offset some other JS effect that does not appear when JS is disabled)
//
// === Applied Via
// * class "js_set_padding_UOM_X" --- UOM is either 'px' or 'em' and X specifies the margin of the 4 sides.
//   * X can be a number, this will then be applied to all 4 sides
//   * X can be a set of 4 numbers: t_r_b_l (numbers can be left blank to leave that setting unchanged)
//
// === Example
// * <div id="page_content_frame" class="some_css_class js_set_padding_px_20__20_0 another_css_class">
//
var JSSetPadding = Behavior.create({
  initialize : function() {
    // Determine CSS
    all_css = this.element.readAttribute( 'class' ).split( ' ' )
    for ( var i=0; i < all_css.length; i++ ) {
      css = all_css[ i ].split( '_' ).reverse()
      if ( css.pop() == 'js' && css.pop() == 'set' && css.pop() == 'padding' ) {
        break
      }
    }
    
    // Determine unit of measure
    uom = css.pop()
    if ( uom != 'px' && uom != 'em' ) {
      this.logFBError()
      return
    }
    
    // Determine padding from CSS
    if ( css.length == 1 ) {
      t = r = b = l = parseFloat( css[ 0 ] )
    } else if ( css.length == 4 ) {
      t = parseFloat( css[ 3 ] )
      r = parseFloat( css[ 2 ] )
      b = parseFloat( css[ 1 ] )
      l = parseFloat( css[ 0 ] )
    } else {
      this.logFBError()
      return
    }
    
    // Set new padding
    if ( t !== NaN ) { this.element.setStyle( { paddingTop : t + uom } ) }
    if ( r !== NaN ) { this.element.setStyle( { paddingRight : r + uom } ) }
    if ( b !== NaN ) { this.element.setStyle( { paddingBottom : b + uom } ) }
    if ( l !== NaN ) { this.element.setStyle( { paddingLeft : l + uom } ) }
  },
  logFBError : function() {
    if ( AB_GLOBALS.get( 'RAILS_ENV' ) != 'production' ) {    
      console.group( 'JSSetPadding Error' )
      console.error( 'Could not apply padding to element' )
      console.log( this.element )
      console.group( 'trace' )
      console.trace()
      console.groupEnd()
      console.groupEnd()
    }
  }
})
Event.addBehavior( { 'div[class*=js_set_padding_]': JSSetPadding() } )

// Focuses on field when page loads.
// Note: To avoid problems, only one element per page should have this or SelectOnPageLoad set.
//
// === Applied Via
// * class "focus_on_page_load"
//
// === Example
// * <input type="text" class="focus_on_page_load" />
//
var FocusOnPageLoad = Behavior.create({
	initialize : function() {
	  this.element.focus()
	}
})
Event.addBehavior( { '.focus_on_page_load': FocusOnPageLoad() } )

// Enables js #link scrolling effect
//
// === Applied Via
// * any link that begins with "#"
//
var JSScroll = Behavior.create({
  onclick : function() {
  	temp = this.element.readAttribute( 'href' ).split( '#' )
  	Effect.ScrollTo( temp[ 1 ] )
  	return false
  }
})
Event.addBehavior( { 'a[href^=#]:not([href=#])': JSScroll() } )
/*Event.observe( window, 'load', function() {
  $$( 'a[href^=#]:not([href=#])' ).each( function( element ) {
    new JSScroll( element )
  })
})*/

// Selects field when page loads.
// Note: To avoid problems, only one element per page should have this or FocusOnPageLoad set.
//
// === Applied Via
// * class "select_on_page_load"
//
// === Example
// * <input type="text" class="select_on_page_load" />
//
var SelectOnPageLoad = Behavior.create({
	initialize : function() {
	  this.element.select()
	}
})
Event.addBehavior( { '.select_on_page_load': SelectOnPageLoad() } )