//-----------------------------------
// JQUERY EXTENSIONS
//-----------------------------------

// add a simple 'exists' function
$.fn.exists = function ( ) {
  return $( this  ).length !== 0;
}


//-----------------------------------
// GLOBAL VARIABLES
//-----------------------------------

// define the global list of colors all red if it's not been defined in the template
if( gColors == 'undefined' || gColors == null ) {
  gColors = new Object( );
  gColors['header'] = 'ff0000';
  gColors['headerText'] = 'ff0000';
  gColors['headerBorder'] = 'ff0000';
  gColors['content'] = 'ff0000';
  gColors['contentText'] = 'ff0000';
  gColors['contentTextLight'] = 'ff0000';
  gColors['contentBorder'] = 'ff0000';
  gColors['contentBg'] = 'ff0000';
  gColors['link'] = 'ff0000';
}

// a list of old colors used when cancelling changes
gOldColors = new Object( );
copyColors( gColors, gOldColors );

// a global list of colors that have been modified since the last save
var gModifiedColors = new Object( );


//-----------------------------------
// GLOBAL FUNCTIONS
//-----------------------------------

/**
 * Copies one color object to another.
 */
function copyColors ( pFrom, pTo ) {
  for( var key in pFrom ) {
    pTo[key] = pFrom[key];
  }
}

/**
 * Resets the colors to the system default.
 */
function resetColors ( ) {
  copyColors( gDefaultColors, gColors );
  gModifiedColors['header'] = true;
  gModifiedColors['headerText'] = true;
  gModifiedColors['content'] = true;
  gModifiedColors['contentText'] = true;
  gModifiedColors['contentBg'] = true;
  gModifiedColors['link'] = true;
  ApplyAllColors( );
}

/**
 * Sends an ajax request to update the user's color selections.
 */
function updateColors ( ) {
  var queryString = '';
  for( var type in gModifiedColors ) {
    queryString += 'page[c][' + type + ']=' + gColors[type] + '&';
  }
  if( queryString.length > 0 ) {
    queryString = queryString.substring( 0, queryString.length - 1 );

    // send the ajax call
    $.ajax( {
      type: 'POST',
      url: '/' + gUrls['portalPrefix'] + 'null.xml',
      data: queryString,
      success: function ( pHtml ) {
        $( '#debug' ).append( pHtml );
      }
    } );
  }
  gModifiedColors = new Object( );
  copyColors( gColors, gOldColors );
}

/**
 * Cancels a color change and reverts the colors to the last state.
 */
function cancelColorChange ( ) {
  copyColors( gOldColors, gColors );
  ApplyAllColors( );
}

/**
 * Takes a color in HSB and 'lightens' it by increasing the 'B' value.  This will
 * return the hex value for the color.  NOTE: If lightening the color would result
 * in a 'B' value of > 100, the color will be darkened instead.
 */
function lightenColor ( pHsb, pLevel ) {

  var amount = 20;
  if( pLevel != null ) {
    amount *= pLevel;
  }
  var b = pHsb.b;
  b += amount;
  if( b > 100 ) {
    b -= 2 * amount;
  }
  pHsb.b = b;
  return HSBToHex( pHsb );
}

/**
 * Converts an HSB color to an RGB color.  This is copied directly from the colorpicker
 * class since I can't figure out how to get a reference to a ColorPicker object within
 * the 'change' callback to call the methods within that class.
 */
function HSBToRGB ( pHsb ) {
  var rgb = { };
  var h = Math.round( pHsb.h );
  var s = Math.round( pHsb.s * 255 / 100 );
  var v = Math.round( pHsb.b * 255 / 100 );
  if( s == 0 ) {
    rgb.r = rgb.g = rgb.b = v;
  }
  else {
    var t1 = v;
    var t2 = ( 255 - s ) * v / 255;
    var t3 = ( t1 - t2 ) * ( h % 60 ) / 60;
    if( h == 360 ) h = 0;
    if( h < 60 )       { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
    else if( h < 120 ) { rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
    else if( h < 180 ) { rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
    else if( h < 240 ) { rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
    else if( h < 300 ) { rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
    else if( h < 360 ) { rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
    else               { rgb.r = 0;  rgb.g = 0;  rgb.b = 0}
  }
  return { r:Math.round( rgb.r ), g:Math.round( rgb.g ), b:Math.round( rgb.b ) };
}

/**
 * Converts an RGB color to an HEX color.  This is copied directly from the colorpicker
 * class since I can't figure out how to get a reference to a ColorPicker object within
 * the 'change' callback to call the methods within that class.
 */
function RGBToHex ( pRgb ) {
  var hex = [
    pRgb.r.toString( 16 ),
    pRgb.g.toString( 16 ),
    pRgb.b.toString( 16 )
  ];
  $.each( hex, function ( pNr, pVal ) {
    if( pVal.length == 1 ) {
      hex[pNr] = '0' + pVal;
    }
  } );
  return hex.join( '' );
}

/**
 * Converts an HSB color to an HEX color.  This is copied directly from the colorpicker
 * class since I can't figure out how to get a reference to a ColorPicker object within
 * the 'change' callback to call the methods within that class.
 */
function HSBToHex ( pHsb ) {
  return RGBToHex( HSBToRGB( pHsb ) );
};


//-----------------------------------
// GLOBAL VARIABLES
//-----------------------------------


$( document ).ready( function ( ) {

  // initialize superfish menus
  $( 'ul.navbar-menu' ).not( '.right-cascade' ).not( '.left-cascade' ).addClass( 'left-cascade' );
  $( 'ul.navbar-menu' ).superfish( {
    pathClass: 'current',
    pathLevels: 1,
    delay: 1000
  } ).find( 'ul' ); //.bgIframe( { opacity:false } );

  // make all empty links do nothing
  $( 'ul.navbar-menu a' ).each( function( ) {
    if( $( this ).attr( 'href' ) == '' ) {
      $( this ).bind( 'click', function( ) { return false; } );
    }
  } );

  // enable button mouseovers
  $( '.tbutton' ).each( function( ) {
    if( this.src != null ) {
      this.srcOrig = this.src;
      this.onmouseover = function ( ) {
        this.src = this.src.replace( /_on/, "_over" );
        this.src = this.src.replace( /_off/, "_over" );
      };
      this.onmouseout = function ( ) {
        this.src = this.srcOrig;
      }
    }
  } );

  // add jQuery UI style buttons
  $( 'button, input:submit, a.button' ).button( );

  // add tabs to the color picker dialog
  $( '#color-picker-tabs' ).tabs( );

  // enable opening of the color picker dialog
  $( '#colors_control' ).bind( 'click', function ( ) {
    $( '#color-picker-dialog' ).dialog( {
      width: 415,
      resizable: false,
      close: function ( pEvent, pUi ) {
        cancelColorChange( );
      }
    } );
  } );

  // set up the header color picker
  $( '#header_color_holder' ).ColorPicker( {
    color: '#' + gColors['header'],
    flat: true,
    onChange: function ( pHsv, pHex, pRgb ) {
      var lightColor = lightenColor( pHsv );
      gColors['header'] = pHex;
      gColors['headerBorder'] = lightColor;
      gModifiedColors['header'] = true;
      ApplyHeaderColor( );
    }
  });

  // set up the header text color picker
  $( '#header_text_color_holder').ColorPicker( {
    color: '#' + gColors['headerText'],
    flat: true,
    onChange: function ( pHsv, pHex, pRgb ) {
      gColors['headerText'] = pHex;
      gModifiedColors['headerText'] = true;
      ApplyHeaderTextColor( );
    }
  });

  // set up the content color picker
  $( '#content_color_holder').ColorPicker( {
    color: '#' + gColors['content'],
    flat: true,
    onChange: function ( pHsv, pHex, pRgb ) {
      var lightColor = lightenColor( pHsv );
      gColors['content'] = pHex;
      gColors['contentBorder'] = lightColor;
      gModifiedColors['content'] = true;
      ApplyContentColor( );
    }
  });

  // set up the content text color picker
  $( '#content_text_color_holder').ColorPicker( {
    color: '#' + gColors['contentText'],
    flat: true,
    onChange: function ( pHsv, pHex, pRgb ) {
      var lightColor = lightenColor( pHsv, 2 );
      gColors['contentText'] = pHex;
      gColors['contentTextLight'] = lightColor;
      gModifiedColors['contentText'] = true;
      ApplyContentTextColor( );
    }
  });

  // set up the content area bg color picker
  $( '#content_bg_color_holder' ).ColorPicker( {
    color: '#' + gColors['contentBg'],
    flat: true,
    onChange: function ( pHsv, pHex, pRgb ) {
      gColors['contentBg'] = pHex;
      gModifiedColors['contentBg'] = true;
      ApplyContentBgColor( );
    }
  } );

  // set up the link color picker
  $( '#link_color_holder').ColorPicker( {
    color: '#' + gColors['link'],
    flat: true,
    onChange: function ( pHsv, pHex, pRgb ) {
      gColors['link'] = pHex;
      gModifiedColors['link'] = true;
      ApplyLinkColor( );
    }
  });

  // enable cluetip tooltips
  $( '.tip-control' ).cluetip( {
    showTitle:  false,
    positionBy: 'mouse',
    local:      true,
    dropShadow: false
  } );
} );

function ApplyHeaderColor ( ) {
  $( gSelectors.headerBackground ).css( 'backgroundColor', '#' + gColors['header'] );
  $( gSelectors.headerBorder ).css( 'borderColor', '#' + gColors['headerBorder'] );
  $( gSelectors.headerBoth ).css( 'backgroundColor', '#' + gColors['header'] ).css( 'borderColor', '#' + gColors['headerBorder'] );
}

function ApplyHeaderTextColor ( ) {
  $( gSelectors.headerTextAsBackground ).css( 'backgroundColor', '#' + gColors['headerText'] );
  $( gSelectors.headerText ).css( 'color', '#' + gColors['headerText'] );
}

function ApplyContentColor ( ) {
  $( gSelectors.contentBackground ).css( 'backgroundColor', '#' + gColors['content'] );
  $( gSelectors.contentBorder ).css( 'borderColor', '#' + gColors['contentBorder'] );
  $( gSelectors.contentBoth ).css( 'backgroundColor', '#' + gColors['content'] ).css( 'borderColor', '#' + gColors['contentBorder'] );
}

function ApplyContentTextColor ( ) {
  $( gSelectors.contentTextAsBackground ).css( 'backgroundColor', '#' + gColors['contentText'] );
  $( gSelectors.contentText ).css( 'color', '#' + gColors['contentText'] );
  $( gSelectors.contentTextLight).css( 'color', '#' + gColors['contentTextLight'] );
}

function ApplyContentBgColor ( ) {
  $( gSelectors.contentAreaBackground ).css( 'backgroundColor', '#' + gColors['contentBg'] );
}

function ApplyLinkColor ( ) {
  $( gSelectors.linkTextAsBackground ).css( 'backgroundColor', '#' + gColors['link'] );
  $( gSelectors.linkText ).not( '.header_color a, .ui-widget-header a, #user-links a' ).css( 'color', '#' + gColors['link'] );
}

function ApplyAllColors ( ) {
  ApplyHeaderColor ( );
  ApplyHeaderTextColor ( );
  ApplyContentColor ( );
  ApplyContentTextColor ( );
  ApplyContentBgColor ( );
  ApplyLinkColor ( );
}
