var IMAGE_SIZE = 150;
var COLOUR_RADIUS_MIN = 29;
var COLOUR_RADIUS_MAX = 147;
var COLOUR_ANGULAR_WIDTH = 15;
var INDICATOR_RADIUS = 24;
var INDICATOR_OFFSET = 2;

var WHEEL_COLOURS = new Array(24);
WHEEL_COLOURS['0']   = new Array(255,0,0,    0, 1, 1);
WHEEL_COLOURS['15']  = new Array(255,51,0,   12, 1, 1);
WHEEL_COLOURS['30']  = new Array(255,102,0,  24, 1, 1);
WHEEL_COLOURS['45']  = new Array(255,128,0,  30, 1, 1);
WHEEL_COLOURS['60']  = new Array(255,153,0,  36, 1, 1);
WHEEL_COLOURS['75']  = new Array(255,178,0,  42, 1, 1);
WHEEL_COLOURS['90']  = new Array(255,204,0,  48, 1, 1);
WHEEL_COLOURS['105'] = new Array(255,229,0,  54, 1, 1);
WHEEL_COLOURS['120'] = new Array(255,255,0,  60, 1, 1);
WHEEL_COLOURS['135'] = new Array(204,255,0,  72, 1, 1);
WHEEL_COLOURS['150'] = new Array(153,255,0,  84, 1, 1);
WHEEL_COLOURS['165'] = new Array(51,255,0,   108, 1, 1);
WHEEL_COLOURS['180'] = new Array(0,204,0,    120, 1, 0.8);
WHEEL_COLOURS['195'] = new Array(0,178,102,  154, 1, 0.7);
WHEEL_COLOURS['210'] = new Array(0,153,153,  180, 1, 0.6);
WHEEL_COLOURS['225'] = new Array(0,102,178,  206, 1, 0.7);
WHEEL_COLOURS['240'] = new Array(0,51,204,   225, 1, 0.8);
WHEEL_COLOURS['255'] = new Array(25,25,178,  240, 0.86, 0.7);
WHEEL_COLOURS['270'] = new Array(51,0,153,   260, 1, 0.6);
WHEEL_COLOURS['285'] = new Array(64,0,153,   265, 1, 0.6);
WHEEL_COLOURS['300'] = new Array(102,0,153,  280, 1, 0.6);
WHEEL_COLOURS['315'] = new Array(153,0,153,  300, 1, 0.6);
WHEEL_COLOURS['330'] = new Array(204,0,153,  315, 1, 0.8);
WHEEL_COLOURS['345'] = new Array(229,0,102,  333, 1, 0.9);

var SHADES = new Array(6);
SHADES[0] = new Array(1, 1,
                      0.5, 1,
                      0.25, 1,
                      0.667, 0.667,
                      0.667, 0.333,
                      0.5, 0.75,
                      0.25, 0.875,
                      1, 0.7);
SHADES[1] = new Array(0.25, 1,
                      0.5, 1,
                      0.1, 1,
                      0.5, 0.75,
                      0.333, 0.333,
                      0.25, 0.75,
                      0.125, 0.875,
                      0.5, 0.7);
SHADES[2] = new Array(0.5, 0.9,
                      0.75, 0.75,
                      0.1, 0.9,
                      0.5, 0.5,
                      0.333, 0.3,
                      0.25, 0.5,
                      0.125, 0.75,
                      0.5, 0.5);
SHADES[3] = new Array(0.3, 0.8,
                      0.5, 0.75,
                      0.1, 0.9,
                      0.3, 0.5,
                      0.333, 0.25,
                      0.25, 0.4,
                      0.125, 0.6,
                      0.5, 0.4);
SHADES[4] = new Array(1, 1,
                      0.75, 1,
                      0.5, 1,
                      0.8, 0.85,
                      0.25, 1,
                      0.75, 0.9,
                      0.5, 0.95,
                      1, 0.9);
SHADES[5] = new Array(0.4, 0.85,
                      0.4, 0.75,
                      0.4, 1,
                      0.4, 0.5,
                      0.2, 0.85,
                      0.2, 0.75,
                      0.2, 1,
                      0.2, 0.5);

var colourAngle;
var shade = 0;
var eyedropId = false;
var colourAngleId;
var chosenSchemeId;
var chosenShadeId;

function wheelClicked(ev)
{
  /**
   * Get the position of the click relative to the colour wheel.
   */
  var clickX = ev.pointerX() - $('wheel').cumulativeOffset()[0];
  var clickY = ev.pointerY() - $('wheel').cumulativeOffset()[1];

  /**
   * Get the position of the click relative to the centre of the
   * wheel
   */
  var x = (IMAGE_SIZE - clickX);
  var y = (clickY - IMAGE_SIZE);

  /**
   * Translate to polar co-ordinates.
   */
  var angle = Math.round(((Math.atan2(x, y) * 180/Math.PI) + 180) % 360);
  var radius = Math.sqrt((x * x) + (y * y));

  /**
   * If the click is within the colour bar area then we have a new
   * colour.  Move the indicators to the appropriate position.
   */
  if ((radius >= COLOUR_RADIUS_MIN) &&
      (radius <= COLOUR_RADIUS_MAX))
  {
    colourAngle = (Math.floor((angle - (COLOUR_ANGULAR_WIDTH / 2)) /
                              COLOUR_ANGULAR_WIDTH + 1) * 15) % 360;
    $(colourAngleId).value = colourAngle;
    updateColours();
  }
}

function updateColours()
{
  switch ($(chosenShadeId).value)
  {
    case "LPASTEL":
      shade = 1;
      break;

    case "PASTEL":
      shade = 2;
      break;

    case "DPASTEL":
      shade = 3;
      break;

    case "BRIGHT":
      shade = 4;
      break;

    case "PALE":
      shade = 5;
      break;

    default:
      shade = 0;
      break;
  }

  if ($(chosenSchemeId).value != "GREY")
  {
    showColour(0, colourAngle);
    showIndicator(0, colourAngle);
    showShades();
  }
  else
  {
    showColour(0, -1);
    hideIndicator(0);
    hideShades();
  }

  switch ($(chosenSchemeId).value)
  {
    case "COMP":
      showColour(1, (colourAngle + 180) % 360);
      hideColour(2);
      hideColour(3);
      break;

    case "ANA":
      showColour(1, (colourAngle + 330) % 360);
      showColour(2, (colourAngle + 30) % 360);
      hideColour(3);
      break;

    case "ANAC":
      showColour(1, (colourAngle + 330) % 360);
      showColour(2, (colourAngle + 30) % 360);
      showColour(3, (colourAngle + 180) % 360);
      break;

    case "SPLIT":
      showColour(1, (colourAngle + 150) % 360);
      showColour(2, (colourAngle + 210) % 360);
      hideColour(3);
      break;

    case "TRIAD":
      showColour(1, (colourAngle + 120) % 360);
      showColour(2, (colourAngle + 240) % 360);
      hideColour(3);
      break;

    case "TETRAD":
      showColour(1, (colourAngle + 330) % 360);
      showColour(2, (colourAngle + 150) % 360);
      showColour(3, (colourAngle + 180) % 360);
      break;

    default:
      hideColour(1);
      hideColour(2);
      hideColour(3);
      break;
  }

  for (var ii = 0; ii < propertyList.length; ii++)
  {
    if (($(propertyList[ii][0] + 'I').value) &&
        (($(propertyList[ii][0] + 'I').value.replace(/\d$/, '') == 'colour4') ||
         ($($(propertyList[ii][0] + 'I').value.replace(/\d$/, '')).getStyle('display') != 'none')) &&
        ($(propertyList[ii][0] + 'L').src.search(/lock_open\.png/) != -1))
    {
      var hex = $($(propertyList[ii][0] + 'I').value).
                                                     getAttribute('rawColour');
      changePickedColour(propertyList[ii][0], hex);
    }
    else if (!$(propertyList[ii][0] + 'I').value)
    {
      undefProperty(propertyList[ii][0]);
    }
    else
    {
      changePickedColour(propertyList[ii][0], $(propertyList[ii][0]).value);
    }
  }
  
  coloursChanged();
}

function toggleLock(id)
{
  if ($(id + 'L').src.search(/lock_open\.png/) == -1)
  {
    $(id + 'L').src = $(id + 'L').src.replace(/lock\.png/, 'lock_open.png');
    $(id + 'L').alt = 'Lock';
  }
  else
  {
    $(id + 'L').src = $(id + 'L').src.replace(/lock_open\.png/, 'lock.png');
    $(id + 'L').alt = 'Unlock';
  }
  return(false);
}

function changePickedColour(id, colour)
{
  $(id + 'D').setStyle({background: colour});
  $(id).value = colour;
  addUpdateCSSRule(id, colour);

  if ($(id + 'X'))
  {
    $(id + 'X').src = 'images/v2/cross.png';
  }
}

function undefProperty(id)
{
  $(id + 'D').setStyle({background: "url(images/transparent.png)"});
  $(id + 'I').value = '';
  $(id + 'X').src = 'images/v2/cross_dis.png';
  $(id).value = '';
  addUpdateCSSRule(id, false);
}

function addUpdateCSSRule(id, colour)
{
  var sheet = document.styleSheets[1];
  var rules;
  var propertyData;
  var value;

  for (var ii = 0; ii < propertyList.length; ii++)
  {
    if (propertyList[ii][0] == id)
    {
      propertyData = propertyList[ii];
      selectors = propertyData[1].split(',');
      break;
    }
  }

  if (sheet.cssRules)
  {
    rules = sheet.cssRules;
  }
  else
  {
    rules = sheet.rules;
  }

  if (sheet.deleteRule)
  {
    for (var ii = (rules.length - 1); ii >= 0; ii--)
    {
      if ((rules[ii].selectorText) &&
          (rules[ii].selectorText.toLowerCase() == propertyData[1]))
      {
        sheet.deleteRule(ii);
        break;
      }
    }
  }
  else if (sheet.removeRule)
  {
    for (var ii = (rules.length - 1); ii >= 0; ii--)
    {
      for (var jj = 0; jj < selectors.length; jj++)
      {
        if ((rules[ii].selectorText) &&
            (rules[ii].selectorText.toLowerCase() == selectors[jj]))
        {
          sheet.removeRule(ii);
          break;
        }
      }
    }
  }

  if (colour)
  {
    value = propertyData[3] + colour;
  }
  else
  {
    value = propertyData[4];
  }

  if (sheet.insertRule)
  {
    sheet.insertRule(propertyData[1] +
                     ' { ' +
                     propertyData[2] +
                     ': ' +
                     value +
                     ';}',
                     sheet.cssRules.length);
  }
  else if (sheet.addRule)
  {
    for (var ii = 0; ii < selectors.length; ii++)
    {
      sheet.addRule(selectors[ii],
                    propertyData[2] +
                    ': ' +
                    value);
    }
  }
}

function showIndicator(index, angle)
{
  var indicatorX = IMAGE_SIZE +
                   10 +
                   Math.floor(INDICATOR_RADIUS *
                                             Math.sin(angle * Math.PI / 180)) -
                   INDICATOR_OFFSET;
  var indicatorY = IMAGE_SIZE +
                   10 -
                   Math.floor(INDICATOR_RADIUS *
                                             Math.cos(angle * Math.PI / 180)) -
                   INDICATOR_OFFSET;
  $('indicator' + index).setStyle({left: indicatorX + "px",
                                   top: indicatorY + "px",
                                   display: 'block'});
}

function hideIndicator(index)
{
  $('indicator' + index).setStyle({display: 'none'});
}

function showColour(column, angle)
{
  $('colour' + column).setStyle({display: 'block'});
  showVariant(column,
              0,
              angle,
              SHADES[shade][0],
              SHADES[shade][1]);
  showVariant(column,
              1,
              angle,
              SHADES[shade][2],
              SHADES[shade][3]);
  showVariant(column,
              2,
              angle,
              SHADES[shade][4],
              SHADES[shade][5]);
  showVariant(column,
              3,
              angle,
              SHADES[shade][6],
              SHADES[shade][7]);
  showVariant(column,
              4,
              angle,
              SHADES[shade][8],
              SHADES[shade][9]);
  showVariant(column,
              5,
              angle,
              SHADES[shade][10],
              SHADES[shade][11]);
  showVariant(column,
              6,
              angle,
              SHADES[shade][12],
              SHADES[shade][13]);
  showVariant(column,
              7,
              angle,
              SHADES[shade][14],
              SHADES[shade][15]);
}

function hideColour(index)
{
  $('colour' + index).setStyle({display: 'none'});
}

function showVariant(column, row, angle, multS, multV)
{
  var hex = getHex(angle, multS, multV);
  $('colour' + column + row).setStyle({background: hex});
  $('colour' + column + row).setAttribute('rawColour', hex);
}

function showShades()
{
  $('shadesDiv').setStyle({display: 'block'});
}

function hideShades()
{
  $('shadesDiv').setStyle({display: 'none'});
}

function eyedropper(id)
{
  for (var ii = 0; ii < propertyList.length; ii++)
  {
    if (propertyList[ii][0] != id)
    {
      $(propertyList[ii][0] + 'P').setStyle({background: 'none',
                                             border: '1px solid #F8F6F1'});
    }
  }

  if (eyedropId != id)
  {
    $(id + 'P').setStyle({background: '#fff',
                          border: '1px solid #000'});
    eyedropId = id;

    for (var ii = 0; ii < 4; ii++)
    {
      for (var jj = 0; jj < 8; jj++)
      {
        $('colour' + ii + jj).setStyle({cursor: 'pointer'});
      }
    }
    $('colour40').setStyle({cursor: 'pointer'});
    $('colour41').setStyle({cursor: 'pointer'});
  }
  else
  {
    $(id + 'P').setStyle({background: 'none',
                          border: '1px solid #F8F6F1'});
    eyedropId = false;

    for (var ii = 0; ii < 4; ii++)
    {
      for (var jj = 0; jj < 8; jj++)
      {
        $('colour' + ii + jj).setStyle({cursor: 'default'});
      }
    }
    $('colour40').setStyle({cursor: 'default'});
    $('colour41').setStyle({cursor: 'default'});
  }

  return(false);
}

function colClick(event)
{
  var colour;
  var el = event.element();

  if (eyedropId)
  {
    colour = el.getAttribute('rawColour');
    $(eyedropId + 'I').value = el.id;
    changePickedColour(eyedropId, colour);
    coloursChanged();
  }
}

function scale(a, b, fraction)
{
  return(a + ((b - a) * fraction));
}

function getHex(angle, multS, multV)
{
  var colH;
  var colS;
  var colV;

  if (angle == -1)
  {
    colH = 0;
    colS = 0;
    colV = (2 + (multS * multS)) / 3;
  }
  else
  {
    var lowerAngle = Math.floor(angle / 15) * 15;

    if (angle == lowerAngle)
    {
      colH = WHEEL_COLOURS[angle][3];
      colS = WHEEL_COLOURS[angle][4];
      colV = WHEEL_COLOURS[angle][5];
    }
    else
    {
      var upperAngle = (lowerAngle + 15) % 360;
      var fraction = (angle - lowerAngle) / 15;
      colH = scale(WHEEL_COLOURS[lowerAngle][3],
                   WHEEL_COLOURS[upperAngle][3],
                   fraction);
      colS = scale(WHEEL_COLOURS[lowerAngle][4],
                   WHEEL_COLOURS[upperAngle][4],
                   fraction);
      colV = scale(WHEEL_COLOURS[lowerAngle][5],
                   WHEEL_COLOURS[upperAngle][5],
                   fraction);
    }
  }
  var RGB = hsv2rgb(colH / 360, colS * multS, colV * multV);
  return('#' +
         dec2hex(RGB['red']) +
         dec2hex(RGB['green']) +
         dec2hex(RGB['blue']));
}

function dec2hex(n)
{
  if (n >= 255) return('FF');
  var s = n.toString(16);
  if (s.length < 2) s = '0' + s;
  return s.toUpperCase();
}

function hsv2rgb(h,s,v)
{
  // Adapted from http://www.easyrgb.com/math.html
  // hsv values = 0 - 1, rgb values = 0 - 255
  var r, g, b;
  var RGB = new Array();
  if (s == 0)
  {
    RGB['red'] = RGB['green'] = RGB['blue'] = Math.round(v * 255);
  }
  else
  {
    // h must be < 1
    var var_h = h * 6;
    if (var_h == 6) var_h = 0;
    //Or ... var_i = floor( var_h )
    var var_i = Math.floor( var_h );
    var var_1 = v*(1-s);
    var var_2 = v*(1-s*(var_h-var_i));
    var var_3 = v*(1-s*(1-(var_h-var_i)));

    switch (var_i)
    {
      case 0:
        var_r = v;
        var_g = var_3;
        var_b = var_1;
        break;

      case 1:
        var_r = var_2;
        var_g = v;
        var_b = var_1;
        break;

      case 2:
        var_r = var_1;
        var_g = v;
        var_b = var_3
        break;

      case 3:
        var_r = var_1;
        var_g = var_2;
        var_b = v;
        break;

      case 4:
        var_r = var_3;
        var_g = var_1;
        var_b = v;
        break;

      default:
        var_r = v;
        var_g = var_1;
        var_b = var_2
        break;
    }

    //rgb results = 0 ÷ 255
    RGB['red']=Math.round(var_r * 255);
    RGB['green']=Math.round(var_g * 255);
    RGB['blue']=Math.round(var_b * 255);
  }

  return(RGB);
}

function initWheel()
{
  for (var ii = 0; ii < 4; ii++)
  {
    for (var jj = 0; jj < 8; jj++)
    {
      initVariant('colour' + ii + jj);
    }
  }

  initVariant('colour40');
  initVariant('colour41');
  $('colour40').setAttribute('rawColour', '#000000');
  $('colour41').setAttribute('rawColour', '#FFFFFF');
  $('wheel').observe('click', wheelClicked);
  showIndicator(0, 0);
  if (!isNaN(parseInt($(colourAngleId).value)))
  {
    colourAngle = parseInt($(colourAngleId).value);
  }
  
  /*
  if ($('simpleScheme').value == '1')
  {
    unlockAll();
  }
  */
  
  updateColours();
}

function initVariant(id)
{
  $(id).observe("click", colClick);
}

function unlockAll()
{
  for (var ii = 0; ii < propertyList.length; ii++)
  {
    $(propertyList[ii][0] + 'L').src = $(propertyList[ii][0] + 'L').src.
                                         replace(/lock\.png/, 'lock_open.png');
    $(propertyList[ii][0] + 'L').alt = 'Lock';
  }
  
  return(false);
}

function switchToAdvanced()
{
  $('simpleScheme').value = '0';
  $('simpleInstructionsDiv').style.display = 'none';
  $('paletteDiv').style.display = 'block';
  $('advancedInstructionsDiv').style.display = 'block';
  $('propertiesDiv').style.display = 'block';
  $('colourWheelAdvancedDiv').style.display = 'block';
}

function switchToBasic(homepage)
{
  $('simpleScheme').value = '1';
  $('paletteDiv').style.display = 'none';
  $('advancedInstructionsDiv').style.display = 'none';
  $('propertiesDiv').style.display = 'none';
  $('colourWheelAdvancedDiv').style.display = 'none';
  $('simpleInstructionsDiv').style.display = 'block';
  
  unlockAll();
  
  if (homepage)
  {
    $('homePageColourScheme').value = 'MONO';
    $('homePageColourShade').value = 'DFLT';
    $('homePageBGColI').value = 'colour02';
    $('homePageFGColI').value = 'colour02';
    $('homePageTextColI').value = 'colour04';
    $('homePageBordersColI').value = 'colour40';
  }
  else
  {
    $('siteColourScheme').value = 'MONO';
    $('siteColourShade').value = 'DFLT';
    $('mainCol1I').value = 'colour02';
    $('mainCol2I').value = 'colour06';
    $('mainCol3I').value = 'colour03';
    $('mainTextCol1I').value = 'colour40';
    $('mainTextCol1I').value = 'colour40';
  }
  
  updateColours();
}

function hexEdit(id)
{
  var options = "toolbar=no,status=no,resizable=yes,dependent=yes," +
                "scrollbars=yes";
  options += ",width=" + 500 ;
  options += ",height=" + 200 ;
  openPopup("page.do?dsb/editWebsite/hexEdit" +
            "&id=" + id +
            "&value=" + encodeURIComponent(String.interpret($(id).value)),
            "hexEditWindow",
            options,
            "Your browser blocked the colour edit popup.  Please add dreamshared.com to the list of sites that are allowed to open popup windows.");
}

function hexEdited(id, value)
{
  $(id + 'I').value = '';
  changePickedColour(id, value);
  coloursChanged();  
}
