text: # --------------------------------------------------------------------------- #
  # CUBECOLOURDIALOG Widget wxPython IMPLEMENTATION
  #
  # Python Code By:
  #
  # Andrea Gavana, @ 16 Aug 2007
  # Latest Revision: 26 Feb 2012, 15.00 GMT
  #
  #
  # TODO List
  #
  # 1. Find A Way To Reduce Flickering On The 2 ColourPanels;
  #
  # 2. See Why wx.GCDC Doesn't Work As I Thought (!). It Looks Slow As A Turtle,
  #    But Probably I Am Doing Something Wrong While Painting The Alpha Textures.
  #
  #
  # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
  # Write To Me At:
  #
  # andrea.gavana@gmail.com
  # andrea.gavana@maerskoil.com
  #
  # Or, Obviously, To The wxPython Mailing List!!!
  #
  #
  # End Of Comments
  # --------------------------------------------------------------------------- #
  
  """
  :class:`CubeColourDialog` is an alternative implementation of :class:`ColourDialog`.
  
  
  Description
  ===========
  
  The :class:`CubeColourDialog` is an alternative implementation of :class:`ColourDialog`, and it
  offers different functionalities with respect to the default wxPython one. It
  can be used as a replacement of :class:`ColourDialog` with exactly the same syntax and
  methods.
  
  Some features:
  
  - RGB components may be controlled using spin controls or with mouse gestures
    on a 3D RGB cube, with the 3 components laying on the X, Y, Z axes;
  - HSB components may be controlled using spin controls or with mouse gestures
    on a 2D colour wheel;
  - Brightness has its own vertical slider to play with;
  - The colour alpha channel can be controlled using another vertical slider, or
    via spin control;
  - The colour alpha channel controls can be completely hidden at startup or the
    choice to use the alpha channel can be left to the user while playing with the
    dialog, via a simple :class:`CheckBox`;
  - The "old colour" and "new colour" are displayed in two small custom panel,
    which support alpha transparency and texture;
  - :class:`CubeColourDialog` displays also the HTML colour code in hexadecimal format;
  - When available, a corresponding "Web Safe" colour is generated using a 500
    web colours "database" (a dictionary inside the widget source code). Web Safe
    colours are recognized by all the browsers;
  - When available, a corresponding "HTML name" for the selected colour is displayed,
    by using the same 500 web colours "database";
  - When available, a corresponding "Microsoft Access Code" for the selected colour
    is displayed, by using the same 500 web colours "database".
      
  And much more.
  
  
  Usage
  =====
  
  Usage example::
  
      import wx
      import wx.lib.agw.cubecolourdialog as CCD
  
      # Our normal wxApp-derived class, as usual
      app = wx.App(0)
      
      colourData = wx.ColourData()
      dlg = CCD.CubeColourDialog(None, colourData)
  
      if dlg.ShowModal() == wx.ID_OK:
  
          # If the user selected OK, then the dialog's wx.ColourData will
          # contain valid information. Fetch the data ...
          colourData = dlg.GetColourData()
          h, s, v, a = dlg.GetHSVAColour()
  
          # ... then do something with it. The actual colour data will be
          # returned as a three-tuple (r, g, b) in this particular case.
          colour = colourData.GetColour()
          r, g, b, alpha = colour.Red(), colour.Green(), colour.Blue(), colour.Alpha()
          print "You selected (RGBA): %d, %d, %d, %d"%(r, g, b, alpha)
          print "You selected (HSVA): %d, %d, %d, %d"%(h, s, v, a)
  
      # Once the dialog is destroyed, Mr. wx.ColourData is no longer your
      # friend. Don't use it again!
      dlg.Destroy()
  
      app.MainLoop()
      
  
  
  Window Styles
  =============
  
  This class supports the following window styles:
  
  ================== =========== ==================================================
  Window Styles      Hex Value   Description
  ================== =========== ==================================================
  ``CCD_SHOW_ALPHA``         0x1 Show the widget used to control colour alpha channels in :class:`CubeColourDialog`.
  ================== =========== ==================================================
  
  
  Events Processing
  =================
  
  `No custom events are available for this class.`
  
  
  License And Version
  ===================
  
  :class:`CubeColourDialog` is distributed under the wxPython license. 
  
  Latest Revision: Andrea Gavana @ 26 Feb 2012, 15.00 GMT
  
  Version 0.4.
  
  """
  
  __docformat__ = "epytext"
  
  
  #----------------------------------------------------------------------
  # Beginning Of CUBECOLOURDIALOG wxPython Code
  #----------------------------------------------------------------------
  
  import wx
  import colorsys
  
  from math import pi, sin, cos, sqrt, atan2
  
  from wx.lib.embeddedimage import PyEmbeddedImage
  
  # Define a translation string
  _ = wx.GetTranslation
  
  # Show the alpha control in the dialog
  CCD_SHOW_ALPHA = 1
  """ Show the widget used to control colour alpha channels in :class:`CubeColourDialog`. """
  
  # Radius of the HSB colour wheel
  RADIUS = 100
  """ Radius of the HSB colour wheel. """
  
  # Width of the mouse-controlled colour pointer
  RECT_WIDTH = 5
  """ Width of the mouse-controlled colour pointer. """
  
  # Dictionary keys for the RGB colour cube
  RED, GREEN, BLUE = 0, 1, 2
  """ Dictionary keys for the RGB colour cube. """
  
  Vertex = wx.Point(95, 109)
  Top = wx.Point(95, 10)
  Left = wx.Point(16, 148)
  Right = wx.Point(174, 148)
  
  colourAttributes = ["r", "g", "b", "h", "s", "v"]
  colourMaxValues = [255, 255, 255, 359, 255, 255]
  checkColour = wx.Colour(200, 200, 200)
  
  HTMLCodes = {'#B0171F': ['Indian red', '2037680', ''],
               '#DC143C': ['Crimson', '3937500', '#CC0033'],
               '#FFB6C1': ['Lightpink', '12695295', '#FFCCCC'],
               '#FFAEB9': ['Lightpink 1', '12168959', ''],
               '#EEA2AD': ['Lightpink 2', '11379438', ''],
               '#CD8C95': ['Lightpink 3', '9800909', ''],
               '#8B5F65': ['Lightpink 4', '6643595', ''],
               '#FFC0CB': ['Pink', '13353215', '#FFCCCC'],
               '#FFB5C5': ['Pink 1', '12957183', ''],
               '#EEA9B8': ['Pink 2', '12102126', ''],
               '#CD919E': ['Pink 3', '10392013', ''],
               '#8B636C': ['Pink 4', '7103371', ''],
               '#DB7093': ['Palevioletred', '9662683', '#CC6699'],
               '#FF82AB': ['Palevioletred 1', '11240191', ''],
               '#EE799F': ['Palevioletred 2', '10451438', ''],
               '#CD6889': ['Palevioletred 3', '9005261', ''],
               '#8B475D': ['Palevioletred 4', '6113163', ''],
               '#FFF0F5': ['Lavenderblush 1 (lavenderblush)', '16118015', '#FFFFFF'],
               '#EEE0E5': ['Lavenderblush 2', '15065326', ''],
               '#CDC1C5': ['Lavenderblush 3', '12960205', ''],
               '#8B8386': ['Lavenderblush 4', '8815499', ''],
               '#FF3E96': ['Violetred 1', '9846527', ''],
               '#EE3A8C': ['Violetred 2', '9190126', ''],
               '#CD3278': ['Violetred 3', '7877325', ''],
               '#8B2252': ['Violetred 4', '5382795', ''],
               '#FF69B4': ['Hotpink', '11823615', '#FF66CC'],
               '#FF6EB4': ['Hotpink 1', '11824895', ''],
               '#EE6AA7': ['Hotpink 2', '10971886', ''],
               '#CD6090': ['Hotpink 3', '9461965', ''],
               '#8B3A62': ['Hotpink 4', '6437515', ''],
               '#872657': ['Raspberry', '5711495', ''],
               '#FF1493': ['Deeppink 1 (deeppink)', '9639167', '#FF0099'],
               '#EE1289': ['Deeppink 2', '8983278', ''],
               '#CD1076': ['Deeppink 3', '7737549', ''],
               '#8B0A50': ['Deeppink 4', '5245579', ''],
               '#FF34B3': ['Maroon 1', '11744511', ''],
               '#EE30A7': ['Maroon 2', '10957038', ''],
               '#CD2990': ['Maroon 3', '9447885', ''],
               '#8B1C62': ['Maroon 4', '6429835', ''],
               '#C71585': ['Mediumvioletred', '8721863', '#CC0066'],
               '#D02090': ['Violetred', '9445584', ''],
               '#DA70D6': ['Orchid', '14053594', '#CC66CC'],
               '#FF83FA': ['Orchid 1', '16417791', ''],
               '#EE7AE9': ['Orchid 2', '15301358', ''],
               '#CD69C9': ['Orchid 3', '13199821', ''],
               '#8B4789': ['Orchid 4', '8996747', ''],
               '#D8BFD8': ['Thistle', '14204888', '#CCCCCC'],
               '#FFE1FF': ['Thistle 1', '16769535', ''],
               '#EED2EE': ['Thistle 2', '15651566', ''],
               '#CDB5CD': ['Thistle 3', '13481421', ''],
               '#8B7B8B': ['Thistle 4', '9141131', ''],
               '#FFBBFF': ['Plum 1', '16759807', ''],
               '#EEAEEE': ['Plum 2', '15642350', ''],
               '#CD96CD': ['Plum 3', '13473485', ''],
               '#8B668B': ['Plum 4', '9135755', ''],
               '#DDA0DD': ['Plum', '14524637', '#CC99CC'],
               '#EE82EE': ['Violet', '15631086', '#FF99FF'],
               '#FF00FF': ['Magenta (fuchsia)', '16711935', '#FF00FF'],
               '#EE00EE': ['Magenta 2', '15597806', ''],
               '#CD00CD': ['Magenta 3', '13435085', ''],
               '#8B008B': ['Magenta 4 (darkmagenta)', '9109643', '#990099'],
               '#800080': ['Purple', '8388736', '#990099'],
               '#BA55D3': ['Mediumorchid', '13850042', '#CC66CC'],
               '#E066FF': ['Mediumorchid 1', '16738016', ''],
               '#D15FEE': ['Mediumorchid 2', '15622097', ''],
               '#B452CD': ['Mediumorchid 3', '13456052', ''],
               '#7A378B': ['Mediumorchid 4', '9123706', ''],
               '#9400D3': ['Darkviolet', '13828244', '#9900CC'],
               '#9932CC': ['Darkorchid', '13382297', '#9933CC'],
               '#BF3EFF': ['Darkorchid 1', '16727743', ''],
               '#B23AEE': ['Darkorchid 2', '15612594', ''],
               '#9A32CD': ['Darkorchid 3', '13447834', ''],
               '#68228B': ['Darkorchid 4', '9118312', ''],
               '#4B0082': ['Indigo', '8519755', '#330099'],
               '#8A2BE2': ['Blueviolet', '14822282', '#9933FF'],
               '#9B30FF': ['Purple 1', '16724123', ''],
               '#912CEE': ['Purple 2', '15608977', ''],
               '#7D26CD': ['Purple 3', '13444733', ''],
               '#551A8B': ['Purple 4', '9116245', ''],
               '#9370DB': ['Mediumpurple', '14381203', '#9966CC'],
               '#AB82FF': ['Mediumpurple 1', '16745131', ''],
               '#9F79EE': ['Mediumpurple 2', '15628703', ''],
               '#8968CD': ['Mediumpurple 3', '13461641', ''],
               '#5D478B': ['Mediumpurple 4', '9127773', ''],
               '#483D8B': ['Darkslateblue', '9125192', '#333399'],
               '#8470FF': ['Lightslateblue', '16740484', ''],
               '#7B68EE': ['Mediumslateblue', '15624315', '#6666FF'],
               '#6A5ACD': ['Slateblue', '13458026', '#6666CC'],
               '#836FFF': ['Slateblue 1', '16740227', ''],
               '#7A67EE': ['Slateblue 2', '15624058', ''],
               '#6959CD': ['Slateblue 3', '13457769', ''],
               '#473C8B': ['Slateblue 4', '9124935', ''],
               '#F8F8FF': ['Ghostwhite', '16775416', '#FFFFFF'],
               '#E6E6FA': ['Lavender', '16443110', '#FFFFFF'],
               '#0000FF': ['Blue', '16711680', '#0000FF'],
               '#0000EE': ['Blue 2', '15597568', ''],
               '#0000CD': ['Blue 3 (mediumblue)', '13434880', '#0000CC'],
               '#00008B': ['Blue 4 (darkblue)', '9109504', '#000099'],
               '#000080': ['Navy', '8388608', '#000099'],
               '#191970': ['Midnightblue', '7346457', '#000066'],
               '#3D59AB': ['Cobalt', '11229501', ''],
               '#4169E1': ['Royalblue', '14772545', '#3366CC'],
               '#4876FF': ['Royalblue 1', '16741960', ''],
               '#436EEE': ['Royalblue 2', '15625795', ''],
               '#3A5FCD': ['Royalblue 3', '13459258', ''],
               '#27408B': ['Royalblue 4', '9125927', ''],
               '#6495ED': ['Cornflowerblue', '15570276', '#6699FF'],
               '#B0C4DE': ['Lightsteelblue', '14599344', '#99CCCC'],
               '#CAE1FF': ['Lightsteelblue 1', '16769482', ''],
               '#BCD2EE': ['Lightsteelblue 2', '15651516', ''],
               '#A2B5CD': ['Lightsteelblue 3', '13481378', ''],
               '#6E7B8B': ['Lightsteelblue 4', '9141102', ''],
               '#778899': ['Lightslategray', '10061943', '#669999'],
               '#708090': ['Slategray', '9470064', '#669999'],
               '#C6E2FF': ['Slategray 1', '16769734', ''],
               '#B9D3EE': ['Slategray 2', '15651769', ''],
               '#9FB6CD': ['Slategray 3', '13481631', ''],
               '#6C7B8B': ['Slategray 4', '9141100', ''],
               '#1E90FF': ['Dodgerblue 1 (dodgerblue)', '16748574', '#3399FF'],
               '#1C86EE': ['Dodgerblue 2', '15631900', ''],
               '#1874CD': ['Dodgerblue 3', '13464600', ''],
               '#104E8B': ['Dodgerblue 4', '9129488', ''],
               '#F0F8FF': ['Aliceblue', '16775408', '#FFFFFF'],
               '#4682B4': ['Steelblue', '11829830', '#3399CC'],
               '#63B8FF': ['Steelblue 1', '16758883', ''],
               '#5CACEE': ['Steelblue 2', '15641692', ''],
               '#4F94CD': ['Steelblue 3', '13472847', ''],
               '#36648B': ['Steelblue 4', '9135158', ''],
               '#87CEFA': ['Lightskyblue', '16436871', '#99CCFF'],
               '#B0E2FF': ['Lightskyblue 1', '16769712', ''],
               '#A4D3EE': ['Lightskyblue 2', '15651748', ''],
               '#8DB6CD': ['Lightskyblue 3', '13481613', ''],
               '#607B8B': ['Lightskyblue 4', '9141088', ''],
               '#87CEFF': ['Skyblue 1', '16764551', ''],
               '#7EC0EE': ['Skyblue 2', '15646846', ''],
               '#6CA6CD': ['Skyblue 3', '13477484', ''],
               '#4A708B': ['Skyblue 4', '9138250', ''],
               '#87CEEB': ['Skyblue', '15453831', '#99CCFF'],
               '#00BFFF': ['Deepskyblue 1 (deepskyblue)', '16760576', '#00CCFF'],
               '#00B2EE': ['Deepskyblue 2', '15643136', ''],
               '#009ACD': ['Deepskyblue 3', '13474304', ''],
               '#00688B': ['Deepskyblue 4', '9136128', ''],
               '#33A1C9': ['Peacock', '13214003', ''],
               '#ADD8E6': ['Lightblue', '15128749', '#99CCFF'],
               '#BFEFFF': ['Lightblue 1', '16773055', ''],
               '#B2DFEE': ['Lightblue 2', '15654834', ''],
               '#9AC0CD': ['Lightblue 3', '13484186', ''],
               '#68838B': ['Lightblue 4', '9143144', ''],
               '#B0E0E6': ['Powderblue', '15130800', '#CCCCFF'],
               '#98F5FF': ['Cadetblue 1', '16774552', ''],
               '#8EE5EE': ['Cadetblue 2', '15656334', ''],
               '#7AC5CD': ['Cadetblue 3', '13485434', ''],
               '#53868B': ['Cadetblue 4', '9143891', ''],
               '#00F5FF': ['Turquoise 1', '16774400', ''],
               '#00E5EE': ['Turquoise 2', '15656192', ''],
               '#00C5CD': ['Turquoise 3', '13485312', ''],
               '#00868B': ['Turquoise 4', '9143808', ''],
               '#5F9EA0': ['Cadetblue', '10526303', '#669999'],
               '#00CED1': ['Darkturquoise', '13749760', '#00CCCC'],
               '#F0FFFF': ['Azure 1 (azure)', '16777200', '#FFFFFF'],
               '#E0EEEE': ['Azure 2', '15658720', ''],
               '#C1CDCD': ['Azure 3', '13487553', ''],
               '#838B8B': ['Azure 4', '9145219', ''],
               '#E0FFFF': ['Lightcyan 1 (lightcyan)', '16777184', '#CCFFFF'],
               '#D1EEEE': ['Lightcyan 2', '15658705', ''],
               '#B4CDCD': ['Lightcyan 3', '13487540', ''],
               '#7A8B8B': ['Lightcyan 4', '9145210', ''],
               '#BBFFFF': ['Paleturquoise 1', '16777147', ''],
               '#AEEEEE': ['Paleturquoise 2 (paleturquoise)', '15658670', ''],
               '#96CDCD': ['Paleturquoise 3', '13487510', ''],
               '#668B8B': ['Paleturquoise 4', '9145190', ''],
               '#2F4F4F': ['Darkslategray', '5197615', '#336666'],
               '#97FFFF': ['Darkslategray 1', '16777111', ''],
               '#8DEEEE': ['Darkslategray 2', '15658637', ''],
               '#79CDCD': ['Darkslategray 3', '13487481', ''],
               '#528B8B': ['Darkslategray 4', '9145170', ''],
               '#00FFFF': ['Cyan / aqua', '16776960', '#00FFFF'],
               '#00EEEE': ['Cyan 2', '15658496', ''],
               '#00CDCD': ['Cyan 3', '13487360', ''],
               '#008B8B': ['Cyan 4 (darkcyan)', '9145088', '#009999'],
               '#008080': ['Teal', '8421376', '#009999'],
               '#48D1CC': ['Mediumturquoise', '13422920', '#33CCCC'],
               '#20B2AA': ['Lightseagreen', '11186720', '#339999'],
               '#03A89E': ['Manganeseblue', '10397699', ''],
               '#40E0D0': ['Turquoise', '13688896', '#33CCCC'],
               '#808A87': ['Coldgrey', '8882816', ''],
               '#00C78C': ['Turquoiseblue', '9225984', ''],
               '#7FFFD4': ['Aquamarine 1 (aquamarine)', '13959039', '#66FFCC'],
               '#76EEC6': ['Aquamarine 2', '13037174', ''],
               '#66CDAA': ['Aquamarine 3 (mediumaquamarine)', '11193702', '#66CC99'],
               '#458B74': ['Aquamarine 4', '7637829', ''],
               '#00FA9A': ['Mediumspringgreen', '10156544', '#00FF99'],
               '#F5FFFA': ['Mintcream', '16449525', '#FFFFFF'],
               '#00FF7F': ['Springgreen', '8388352', '#00FF66'],
               '#00EE76': ['Springgreen 1', '7794176', ''],
               '#00CD66': ['Springgreen 2', '6737152', ''],
               '#008B45': ['Springgreen 3', '4557568', ''],
               '#3CB371': ['Mediumseagreen', '7451452', '#33CC66'],
               '#54FF9F': ['Seagreen 1', '10485588', ''],
               '#4EEE94': ['Seagreen 2', '9760334', ''],
               '#43CD80': ['Seagreen 3', '8441155', ''],
               '#2E8B57': ['Seagreen 4 (seagreen)', '5737262', '#339966'],
               '#00C957': ['Emeraldgreen', '5753088', ''],
               '#BDFCC9': ['Mint', '13237437', ''],
               '#3D9140': ['Cobaltgreen', '4231485', ''],
               '#F0FFF0': ['Honeydew 1 (honeydew)', '15794160', '#FFFFFF'],
               '#E0EEE0': ['Honeydew 2', '14741216', ''],
               '#C1CDC1': ['Honeydew 3', '12701121', ''],
               '#838B83': ['Honeydew 4', '8620931', ''],
               '#8FBC8F': ['Darkseagreen', '9419919', '#99CC99'],
               '#C1FFC1': ['Darkseagreen 1', '12713921', ''],
               '#B4EEB4': ['Darkseagreen 2', '11857588', ''],
               '#9BCD9B': ['Darkseagreen 3', '10210715', ''],
               '#698B69': ['Darkseagreen 4', '6916969', ''],
               '#98FB98': ['Palegreen', '10025880', '#99FF99'],
               '#9AFF9A': ['Palegreen 1', '10157978', ''],
               '#90EE90': ['Palegreen 2 (lightgreen)', '9498256', '#99FF99'],
               '#7CCD7C': ['Palegreen 3', '8179068', ''],
               '#548B54': ['Palegreen 4', '5540692', ''],
               '#32CD32': ['Limegreen', '3329330', '#33CC33'],
               '#228B22': ['Forestgreen', '2263842', '#339933'],
               '#00FF00': ['Green 1 (lime)', '65280', '#00FF00'],
               '#00EE00': ['Green 2', '60928', ''],
               '#00CD00': ['Green 3', '52480', ''],
               '#008B00': ['Green 4', '35584', ''],
               '#008000': ['Green', '32768', '#009900'],
               '#006400': ['Darkgreen', '25600', '#006600'],
               '#308014': ['Sapgreen', '1343536', ''],
               '#7CFC00': ['Lawngreen', '64636', '#66FF00'],
               '#7FFF00': ['Chartreuse 1 (chartreuse)', '65407', '#66FF00'],
               '#76EE00': ['Chartreuse 2', '61046', ''],
               '#66CD00': ['Chartreuse 3', '52582', ''],
               '#458B00': ['Chartreuse 4', '35653', ''],
               '#ADFF2F': ['Greenyellow', '3145645', '#99FF33'],
               '#CAFF70': ['Darkolivegreen 1', '7405514', ''],
               '#BCEE68': ['Darkolivegreen 2', '6876860', ''],
               '#A2CD5A': ['Darkolivegreen 3', '5950882', ''],
               '#6E8B3D': ['Darkolivegreen 4', '4033390', ''],
               '#556B2F': ['Darkolivegreen', '3107669', '#666633'],
               '#6B8E23': ['Olivedrab', '2330219', '#669933'],
               '#C0FF3E': ['Olivedrab 1', '4128704', ''],
               '#B3EE3A': ['Olivedrab 2', '3862195', ''],
               '#9ACD32': ['Olivedrab 3 (yellowgreen)', '3329434', '#99CC33'],
               '#698B22': ['Olivedrab 4', '2263913', ''],
               '#FFFFF0': ['Ivory 1 (ivory)', '15794175', '#FFFFFF'],
               '#EEEEE0': ['Ivory 2', '14741230', ''],
               '#CDCDC1': ['Ivory 3', '12701133', ''],
               '#8B8B83': ['Ivory 4', '8620939', ''],
               '#F5F5DC': ['Beige', '14480885', '#FFFFCC'],
               '#FFFFE0': ['Lightyellow 1 (lightyellow)', '14745599', '#FFFFFF'],
               '#EEEED1': ['Lightyellow 2', '13758190', ''],
               '#CDCDB4': ['Lightyellow 3', '11849165', ''],
               '#8B8B7A': ['Lightyellow 4', '8031115', ''],
               '#FAFAD2': ['Lightgoldenrodyellow', '13826810', '#FFFFCC'],
               '#FFFF00': ['Yellow 1 (yellow)', '65535', '#FFFF00'],
               '#EEEE00': ['Yellow 2', '61166', ''],
               '#CDCD00': ['Yellow 3', '52685', ''],
               '#8B8B00': ['Yellow 4', '35723', ''],
               '#808069': ['Warmgrey', '6914176', ''],
               '#808000': ['Olive', '32896', '#999900'],
               '#BDB76B': ['Darkkhaki', '7059389', '#CCCC66'],
               '#FFF68F': ['Khaki 1', '9434879', ''],
               '#EEE685': ['Khaki 2', '8775406', ''],
               '#CDC673': ['Khaki 3', '7587533', ''],
               '#8B864E': ['Khaki 4', '5146251', ''],
               '#F0E68C': ['Khaki', '9234160', ''],
               '#EEE8AA': ['Palegoldenrod', '11200750', '#FFFF99'],
               '#FFFACD': ['Lemonchiffon 1 (lemonchiffon)', '13499135', '#FFFFCC'],
               '#EEE9BF': ['Lemonchiffon 2', '12577262', ''],
               '#CDC9A5': ['Lemonchiffon 3', '10865101', ''],
               '#8B8970': ['Lemonchiffon 4', '7375243', ''],
               '#FFEC8B': ['Lightgoldenrod 1', '9170175', ''],
               '#EEDC82': ['Lightgoldenrod 2', '8576238', ''],
               '#CDBE70': ['Lightgoldenrod 3', '7388877', ''],
               '#8B814C': ['Lightgoldenrod 4', '5013899', ''],
               '#E3CF57': ['Banana', '5754851', ''],
               '#FFD700': ['Gold 1 (gold)', '55295', '#FFCC00'],
               '#EEC900': ['Gold 2', '51694', ''],
               '#CDAD00': ['Gold 3', '44493', ''],
               '#8B7500': ['Gold 4', '30091', ''],
               '#FFF8DC': ['Cornsilk 1 (cornsilk)', '14481663', '#FFFFCC'],
               '#EEE8CD': ['Cornsilk 2', '13494510', ''],
               '#CDC8B1': ['Cornsilk 3', '11651277', ''],
               '#8B8878': ['Cornsilk 4', '7899275', ''],
               '#DAA520': ['Goldenrod', '2139610', '#CC9933'],
               '#FFC125': ['Goldenrod 1', '2474495', ''],
               '#EEB422': ['Goldenrod 2', '2274542', ''],
               '#CD9B1D': ['Goldenrod 3', '1940429', ''],
               '#8B6914': ['Goldenrod 4', '1337739', ''],
               '#B8860B': ['Darkgoldenrod', '755384', '#CC9900'],
               '#FFB90F': ['Darkgoldenrod 1', '1030655', ''],
               '#EEAD0E': ['Darkgoldenrod 2', '962030', ''],
               '#CD950C': ['Darkgoldenrod 3', '824781', ''],
               '#8B6508': ['Darkgoldenrod 4', '550283', ''],
               '#FFA500': ['Orange 1 (orange)', '42495', '#FF9900'],
               '#EE9A00': ['Orange 2', '39662', ''],
               '#CD8500': ['Orange 3', '34253', ''],
               '#8B5A00': ['Orange 4', '23179', ''],
               '#FFFAF0': ['Floralwhite', '15792895', '#FFFFFF'],
               '#FDF5E6': ['Oldlace', '15136253', '#FFFFFF'],
               '#F5DEB3': ['Wheat', '11788021', '#FFCCCC'],
               '#FFE7BA': ['Wheat 1', '12249087', ''],
               '#EED8AE': ['Wheat 2', '11458798', ''],
               '#CDBA96': ['Wheat 3', '9878221', ''],
               '#8B7E66': ['Wheat 4', '6717067', ''],
               '#FFE4B5': ['Moccasin', '11920639', '#FFCCCC'],
               '#FFEFD5': ['Papayawhip', '14020607', '#FFFFCC'],
               '#FFEBCD': ['Blanchedalmond', '13495295', '#FFFFCC'],
               '#FFDEAD': ['Navajowhite 1 (navajowhite)', '11394815', '#FFCC99'],
               '#EECFA1': ['Navajowhite 2', '10604526', ''],
               '#CDB38B': ['Navajowhite 3', '9155533', ''],
               '#8B795E': ['Navajowhite 4', '6191499', ''],
               '#FCE6C9': ['Eggshell', '13231868', ''],
               '#D2B48C': ['Tan', '9221330', '#CCCC99'],
               '#9C661F': ['Brick', '2057884', ''],
               '#FF9912': ['Cadmiumyellow', '1219071', ''],
               '#FAEBD7': ['Antiquewhite', '14150650', '#FFFFCC'],
               '#FFEFDB': ['Antiquewhite 1', '14413823', ''],
               '#EEDFCC': ['Antiquewhite 2', '13426670', ''],
               '#CDC0B0': ['Antiquewhite 3', '11583693', ''],
               '#8B8378': ['Antiquewhite 4', '7897995', ''],
               '#DEB887': ['Burlywood', '8894686', '#CCCC99'],
               '#FFD39B': ['Burlywood 1', '10212351', ''],
               '#EEC591': ['Burlywood 2', '9553390', ''],
               '#CDAA7D': ['Burlywood 3', '8235725', ''],
               '#8B7355': ['Burlywood 4', '5600139', ''],
               '#FFE4C4': ['Bisque 1 (bisque)', '12903679', '#FFFFCC'],
               '#EED5B7': ['Bisque 2', '12047854', ''],
               '#CDB79E': ['Bisque 3', '10401741', ''],
               '#8B7D6B': ['Bisque 4', '7044491', ''],
               '#E3A869': ['Melon', '6924515', ''],
               '#ED9121': ['Carrot', '2200045', ''],
               '#FF8C00': ['Darkorange', '36095', '#FF9900'],
               '#FF7F00': ['Darkorange 1', '32767', ''],
               '#EE7600': ['Darkorange 2', '30446', ''],
               '#CD6600': ['Darkorange 3', '26317', ''],
               '#8B4500': ['Darkorange 4', '17803', ''],
               '#FF8000': ['Orange', '33023', ''],
               '#FFA54F': ['Tan 1', '5219839', ''],
               '#EE9A49': ['Tan 2', '4823790', ''],
               '#CD853F': ['Tan 3 (peru)', '4163021', '#CC9933'],
               '#8B5A2B': ['Tan 4', '2841227', ''],
               '#FAF0E6': ['Linen', '15134970', '#FFFFFF'],
               '#FFDAB9': ['Peachpuff 1 (peachpuff)', '12180223', '#FFCCCC'],
               '#EECBAD': ['Peachpuff 2', '11389934', ''],
               '#CDAF95': ['Peachpuff 3', '9809869', ''],
               '#8B7765': ['Peachpuff 4', '6649739', ''],
               '#FFF5EE': ['Seashell 1 (seashell)', '15660543', '#FFFFFF'],
               '#EEE5DE': ['Seashell 2', '14607854', ''],
               '#CDC5BF': ['Seashell 3', '12568013', ''],
               '#8B8682': ['Seashell 4', '8554123', ''],
               '#F4A460': ['Sandybrown', '6333684', '#FF9966'],
               '#C76114': ['Rawsienna', '1335751', ''],
               '#D2691E': ['Chocolate', '1993170', '#CC6633'],
               '#FF7F24': ['Chocolate 1', '2392063', ''],
               '#EE7621': ['Chocolate 2', '2193134', ''],
               '#CD661D': ['Chocolate 3', '1926861', ''],
               '#8B4513': ['Chocolate 4 (saddlebrown)', '1262987', '#993300'],
               '#292421': ['Ivoryblack', '2171945', ''],
               '#FF7D40': ['Flesh', '4226559', ''],
               '#FF6103': ['Cadmiumorange', '221695', ''],
               '#8A360F': ['Burntsienna', '997002', ''],
               '#A0522D': ['Sienna', '2970272', '#996633'],
               '#FF8247': ['Sienna 1', '4686591', ''],
               '#EE7942': ['Sienna 2', '4356590', ''],
               '#CD6839': ['Sienna 3', '3762381', ''],
               '#8B4726': ['Sienna 4', '2508683', ''],
               '#FFA07A': ['Lightsalmon 1 (lightsalmon)', '8036607', '#FF9966'],
               '#EE9572': ['Lightsalmon 2', '7509486', ''],
               '#CD8162': ['Lightsalmon 3', '6455757', ''],
               '#8B5742': ['Lightsalmon 4', '4347787', ''],
               '#FF7F50': ['Coral', '5275647', '#FF6666'],
               '#FF4500': ['Orangered 1 (orangered)', '17919', '#FF3300'],
               '#EE4000': ['Orangered 2', '16622', ''],
               '#CD3700': ['Orangered 3', '14285', ''],
               '#8B2500': ['Orangered 4', '9611', ''],
               '#5E2612': ['Sepia', '1189470', ''],
               '#E9967A': ['Darksalmon', '8034025', '#FF9966'],
               '#FF8C69': ['Salmon 1', '6917375', ''],
               '#EE8262': ['Salmon 2', '6456046', ''],
               '#CD7054': ['Salmon 3', '5533901', ''],
               '#8B4C39': ['Salmon 4', '3755147', ''],
               '#FF7256': ['Coral 1', '5665535', ''],
               '#EE6A50': ['Coral 2', '5270254', ''],
               '#CD5B45': ['Coral 3', '4545485', ''],
               '#8B3E2F': ['Coral 4', '3096203', ''],
               '#8A3324': ['Burntumber', '2372490', ''],
               '#FF6347': ['Tomato 1 (tomato)', '4678655', '#FF6633'],
               '#EE5C42': ['Tomato 2', '4349166', ''],
               '#CD4F39': ['Tomato 3', '3755981', ''],
               '#8B3626': ['Tomato 4', '2504331', ''],
               '#FA8072': ['Salmon', '7504122', '#FF9966'],
               '#FFE4E1': ['Mistyrose 1 (mistyrose)', '14804223', '#FFCCFF'],
               '#EED5D2': ['Mistyrose 2', '13817326', ''],
               '#CDB7B5': ['Mistyrose 3', '11909069', ''],
               '#8B7D7B': ['Mistyrose 4', '8093067', ''],
               '#FFFAFA': ['Snow 1 (snow)', '16448255', '#FFFFFF'],
               '#EEE9E9': ['Snow 2', '15329774', ''],
               '#CDC9C9': ['Snow 3', '13224397', ''],
               '#8B8989': ['Snow 4', '9013643', ''],
               '#BC8F8F': ['Rosybrown', '9408444', '#CC9999'],
               '#FFC1C1': ['Rosybrown 1', '12698111', ''],
               '#EEB4B4': ['Rosybrown 2', '11842798', ''],
               '#CD9B9B': ['Rosybrown 3', '10197965', ''],
               '#8B6969': ['Rosybrown 4', '6908299', ''],
               '#F08080': ['Lightcoral', '8421616', '#FF9999'],
               '#CD5C5C': ['Indianred', '6053069', '#CC6666'],
               '#FF6A6A': ['Indianred 1', '6974207', ''],
               '#EE6363': ['Indianred 2', '6513646', ''],
               '#8B3A3A': ['Indianred 4', '3816075', ''],
               '#CD5555': ['Indianred 3', '5592525', ''],
               '#A52A2A': ['Brown', '2763429', '#993333'],
               '#FF4040': ['Brown 1', '4210943', ''],
               '#EE3B3B': ['Brown 2', '3881966', ''],
               '#CD3333': ['Brown 3', '3355597', ''],
               '#8B2323': ['Brown 4', '2302859', ''],
               '#B22222': ['Firebrick', '2237106', '#993333'],
               '#FF3030': ['Firebrick 1', '3158271', ''],
               '#EE2C2C': ['Firebrick 2', '2895086', ''],
               '#CD2626': ['Firebrick 3', '2500301', ''],
               '#8B1A1A': ['Firebrick 4', '1710731', ''],
               '#FF0000': ['Red 1 (red)', '255', '#FF0000'],
               '#EE0000': ['Red 2', '238', ''],
               '#CD0000': ['Red 3', '205', ''],
               '#8B0000': ['Red 4 (darkred)', '139', '#990000'],
               '#800000': ['Maroon', '128', '#990000'],
               '#8E388E': ['Sgi beet', '9320590', ''],
               '#7171C6': ['Sgi slateblue', '13005169', ''],
               '#7D9EC0': ['Sgi lightblue', '12623485', ''],
               '#388E8E': ['Sgi teal', '9342520', ''],
               '#71C671': ['Sgi chartreuse', '7456369', ''],
               '#8E8E38': ['Sgi olivedrab', '3706510', ''],
               '#C5C1AA': ['Sgi brightgray', '11190725', ''],
               '#C67171': ['Sgi salmon', '7434694', ''],
               '#555555': ['Sgi darkgray', '5592405', ''],
               '#1E1E1E': ['Sgi gray 12', '1973790', ''],
               '#282828': ['Sgi gray 16', '2631720', ''],
               '#515151': ['Sgi gray 32', '5329233', ''],
               '#5B5B5B': ['Sgi gray 36', '5987163', ''],
               '#848484': ['Sgi gray 52', '8684676', ''],
               '#8E8E8E': ['Sgi gray 56', '9342606', ''],
               '#AAAAAA': ['Sgi lightgray', '11184810', ''],
               '#B7B7B7': ['Sgi gray 72', '12040119', ''],
               '#C1C1C1': ['Sgi gray 76', '12698049', ''],
               '#EAEAEA': ['Sgi gray 92', '15395562', ''],
               '#F4F4F4': ['Sgi gray 96', '16053492', ''],
               '#FFFFFF': ['White', '16777215', '#FFFFFF'],
               '#F5F5F5': ['White smoke (gray)', '16119285', '#FFFFFF'],
               '#DCDCDC': ['Gainsboro', '14474460', '#CCCCCC'],
               '#D3D3D3': ['Lightgrey', '13882323', '#CCCCCC'],
               '#C0C0C0': ['Silver', '12632256', '#CCCCCC'],
               '#A9A9A9': ['Darkgray', '11119017', '#999999'],
               '#808080': ['Gray', '8421504', ''],
               '#696969': ['Dimgray (gray 42)', '6908265', '#666666'],
               '#000000': ['Black', '0', '#000000'],
               '#FCFCFC': ['Gray 99', '16579836', ''],
               '#FAFAFA': ['Gray 98', '16448250', ''],
               '#F7F7F7': ['Gray 97', '16250871', ''],
               '#F2F2F2': ['Gray 95', '15921906', ''],
               '#F0F0F0': ['Gray 94', '15790320', ''],
               '#EDEDED': ['Gray 93', '15592941', ''],
               '#EBEBEB': ['Gray 92', '15461355', ''],
               '#E8E8E8': ['Gray 91', '15263976', ''],
               '#E5E5E5': ['Gray 90', '15066597', ''],
               '#E3E3E3': ['Gray 89', '14935011', ''],
               '#E0E0E0': ['Gray 88', '14737632', ''],
               '#DEDEDE': ['Gray 87', '14606046', ''],
               '#DBDBDB': ['Gray 86', '14408667', ''],
               '#D9D9D9': ['Gray 85', '14277081', ''],
               '#D6D6D6': ['Gray 84', '14079702', ''],
               '#D4D4D4': ['Gray 83', '13948116', ''],
               '#D1D1D1': ['Gray 82', '13750737', ''],
               '#CFCFCF': ['Gray 81', '13619151', ''],
               '#CCCCCC': ['Gray 80', '13421772', ''],
               '#C9C9C9': ['Gray 79', '13224393', ''],
               '#C7C7C7': ['Gray 78', '13092807', ''],
               '#C4C4C4': ['Gray 77', '12895428', ''],
               '#C2C2C2': ['Gray 76', '12763842', ''],
               '#BFBFBF': ['Gray 75', '12566463', ''],
               '#BDBDBD': ['Gray 74', '12434877', ''],
               '#BABABA': ['Gray 73', '12237498', ''],
               '#B8B8B8': ['Gray 72', '12105912', ''],
               '#B5B5B5': ['Gray 71', '11908533', ''],
               '#B3B3B3': ['Gray 70', '11776947', ''],
               '#B0B0B0': ['Gray 69', '11579568', ''],
               '#ADADAD': ['Gray 68', '11382189', ''],
               '#ABABAB': ['Gray 67', '11250603', ''],
               '#A8A8A8': ['Gray 66', '11053224', ''],
               '#A6A6A6': ['Gray 65', '10921638', ''],
               '#A3A3A3': ['Gray 64', '10724259', ''],
               '#A1A1A1': ['Gray 63', '10592673', ''],
               '#9E9E9E': ['Gray 62', '10395294', ''],
               '#9C9C9C': ['Gray 61', '10263708', ''],
               '#999999': ['Gray 60', '10066329', ''],
               '#969696': ['Gray 59', '9868950', ''],
               '#949494': ['Gray 58', '9737364', ''],
               '#919191': ['Gray 57', '9539985', ''],
               '#8F8F8F': ['Gray 56', '9408399', ''],
               '#8C8C8C': ['Gray 55', '9211020', ''],
               '#8A8A8A': ['Gray 54', '9079434', ''],
               '#878787': ['Gray 53', '8882055', ''],
               '#858585': ['Gray 52', '8750469', ''],
               '#828282': ['Gray 51', '8553090', ''],
               '#7F7F7F': ['Gray 50', '8355711', ''],
               '#7D7D7D': ['Gray 49', '8224125', ''],
               '#7A7A7A': ['Gray 48', '8026746', ''],
               '#787878': ['Gray 47', '7895160', ''],
               '#757575': ['Gray 46', '7697781', ''],
               '#737373': ['Gray 45', '7566195', ''],
               '#707070': ['Gray 44', '7368816', ''],
               '#6E6E6E': ['Gray 43', '7237230', ''],
               '#6B6B6B': ['Gray 42', '7039851', ''],
               '#696969': ['Dimgray (gray 42)', '6908265', '#666666'],
               '#666666': ['Gray 40', '6710886', ''],
               '#636363': ['Gray 39', '6513507', ''],
               '#616161': ['Gray 38', '6381921', ''],
               '#5E5E5E': ['Gray 37', '6184542', ''],
               '#5C5C5C': ['Gray 36', '6052956', ''],
               '#595959': ['Gray 35', '5855577', ''],
               '#575757': ['Gray 34', '5723991', ''],
               '#545454': ['Gray 33', '5526612', ''],
               '#525252': ['Gray 32', '5395026', ''],
               '#4F4F4F': ['Gray 31', '5197647', ''],
               '#4D4D4D': ['Gray 30', '5066061', ''],
               '#4A4A4A': ['Gray 29', '4868682', ''],
               '#474747': ['Gray 28', '4671303', ''],
               '#454545': ['Gray 27', '4539717', ''],
               '#424242': ['Gray 26', '4342338', ''],
               '#404040': ['Gray 25', '4210752', ''],
               '#3D3D3D': ['Gray 24', '4013373', ''],
               '#3B3B3B': ['Gray 23', '3881787', ''],
               '#383838': ['Gray 22', '3684408', ''],
               '#363636': ['Gray 21', '3552822', ''],
               '#333333': ['Gray 20', '3355443', ''],
               '#303030': ['Gray 19', '3158064', ''],
               '#2E2E2E': ['Gray 18', '3026478', ''],
               '#2B2B2B': ['Gray 17', '2829099', ''],
               '#292929': ['Gray 16', '2697513', ''],
               '#262626': ['Gray 15', '2500134', ''],
               '#242424': ['Gray 14', '2368548', ''],
               '#212121': ['Gray 13', '2171169', ''],
               '#1F1F1F': ['Gray 12', '2039583', ''],
               '#1C1C1C': ['Gray 11', '1842204', ''],
               '#1A1A1A': ['Gray 10', '1710618', ''],
               '#171717': ['Gray 9', '1513239', ''],
               '#141414': ['Gray 8', '1315860', ''],
               '#121212': ['Gray 7', '1184274', ''],
               '#0F0F0F': ['Gray 6', '986895', ''],
               '#0D0D0D': ['Gray 5', '855309', ''],
               '#0A0A0A': ['Gray 4', '657930', ''],
               '#080808': ['Gray 3', '526344', ''],
               '#050505': ['Gray 2', '328965', ''],
               '#030303': ['Gray 1', '197379', ''],
               }
  
  
  HSVWheelImage = PyEmbeddedImage(
      "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"
      "YII=")
  
  #----------------------------------------------------------------------
  RGBCubeImage = PyEmbeddedImage(
      "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"
      "RK5CYII=")
  
  
  def rad2deg(x):
      """
      Transforms radians into degrees.
  
      :param `x`: a float representing an angle in radians.    
      """
      
      return 180.0*x/pi
  
  
  def deg2rad(x):
      """
      Transforms degrees into radians.
  
      :param `x`: a float representing an angle in degrees.    
      """
  
      return x*pi/180.0
  
  
  def toscale(x):
      """
      Normalize a value as a function of the radius.
  
      :param `x`: a float value to normalize    
      """ 
  
      return x*RADIUS/255.0
  
  
  def scaletomax(x):
      """
      Normalize a value as a function of the radius.
  
      :param `x`: a float value to normalize    
      """ 
  
      return x*255.0/RADIUS
  
  
  def rgb2html(colour):
      """
      Transforms a RGB triplet into an html hex string.
  
      :param `colour`: a tuple of red, green, blue integers.
      """
  
      hexColour = "#%02x%02x%02x"%(colour.r, colour.g, colour.b)
      return hexColour.upper()
  
      
  def Slope(pt1, pt2):
      """
      Calculates the slope of the line connecting 2 points.
  
      :param `pt1`: an instance of :class:`Point`;
      :param `pt2`: another instance of :class:`Point`.
      """
  
      y = float(pt2.y - pt1.y)
      x = float(pt2.x - pt1.x)
  
      if x:
          return y/x
      else:
          return None
  
  
  def Intersection(line1, line2):
      """
      Calculates the intersection point between 2 lines.
  
      :param `line1`: an instance of :class:`LineDescription`;
      :param `line2`: another instance of :class:`LineDescription`.
      """
  
      if line1.slope == line2.slope:
      
          # Parallel lines, no intersection
          return wx.Point(0, 0)
      
      elif line1.slope is None:
      
          # First Line is vertical, eqn is x=0
          # Put x = 0 in second line eqn to get y
          x = line1.x
          y = line2.slope*x + line2.c
      
      elif line2.slope is None:
      
          # second line is vertical Equation of line is x=0
          # Put x = 0 in first line eqn to get y
          x = line2.x
          y = line1.slope*line2.x + line1.c
      
      else:
      
          y = ((line1.c*line2.slope) - (line2.c*line1.slope))/(line2.slope - line1.slope)
          x = (y - line1.c)/line1.slope
      
  
      return wx.Point(int(x), int(y))
  
  
  def FindC(line):
      """ Internal function. """
  
      if line.slope is None:
          c = line.y
      else:
          c = line.y - line.slope*line.x
      
      return c
  
  
  def PointOnLine(pt1, pt2, length, maxLen):
      """ Internal function. """
  
      a = float(length)
  
      if pt2.x != pt1.x:
      
          m = float((pt2.y - pt1.y))/(pt2.x - pt1.x)
          m2 = m*m
          a2 = a*a
          c = pt1.y - m*pt1.x
          c2 = c*c
  
          A = 1.0
          
          x = pt1.x
  
          B = 2.0 * pt1.x
  
          x *= x
          C = x - a2/(m2 + 1)
          
          x = (B + sqrt(B*B - (4.0*A*C)))/(2.0*A)
          y = m*x + c
          pt = wx.Point(int(x), int(y))
  
          if Distance(pt, pt1) > maxLen or Distance(pt, pt2) > maxLen:
          
              x = (B - sqrt(B*B - (4.0*A*C)))/(2.0*A)
              y = m*x + c
              pt = wx.Point(int(x), int(y))
          
      else:
      
          a2 = a*a
          y = sqrt(a2)
          x = 0.0
          pt = wx.Point(int(x), int(y))
          pt.x += pt1.x
          pt.y += pt1.y
          
          if Distance(pt, pt1) > maxLen or Distance(pt, pt2) > maxLen:
  
              y = -1.0*y        
              pt = wx.Point(int(x), int(y))
              pt.x += pt1.x
              pt.y += pt1.y
      
      return pt
  
  
  def Distance(pt1, pt2):
      """
      Returns the distance between 2 points.
  
      :param `pt1`: an instance of :class:`Point`;
      :param `pt2`: another instance of :class:`Point`.    
      """
  
      distance = sqrt((pt1.x - pt2.x)**2.0 + (pt1.y - pt2.y)**2.0)
      return int(distance)
  
  
  def AngleFromPoint(pt, center):
      """
      Returns the angle between the x-axis and the line connecting the center and
      the point `pt`.
  
      :param `pt`: an instance of :class:`Point`;
      :param `center`: a float value representing the center.
      """
  
      y = -1*(pt.y - center.y)
      x = pt.x - center.x
      if x == 0 and y == 0:
      
          return 0.0
      
      else:
      
          return atan2(y, x)
      
  
  def PtFromAngle(angle, sat, center):
      """
      Given the angle with respect to the x-axis, returns the point based on
      the saturation value.
  
      :param `angle`: a float representing an angle;
      :param `sat`: a float representing the colour saturation value;
      :param `center`: a float value representing the center.
      """
  
      angle = deg2rad(angle)
      sat = toscale(sat)
  
      x = sat*cos(angle)
      y = sat*sin(angle)
  
      pt = wx.Point(int(x), -int(y))
      pt.x += center.x
      pt.y += center.y
      
      return pt
  
  
  def RestoreOldDC(dc, oldPen, oldBrush, oldMode):
      """
      Restores the old settings for a :class:`DC`.
  
      :param `dc`: an instance of :class:`DC`;
      :param `oldPen`: an instance of :class:`Pen`;
      :param `oldBrush`: an instance of :class:`Brush`;
      :param `oldMode`: the :class:`DC` drawing mode bit.
      """
  
      dc.SetPen(oldPen)
      dc.SetBrush(oldBrush)
      dc.SetLogicalFunction(oldMode)
  
  
  def DrawCheckerBoard(dc, rect, checkColour, box=5):
      """
      Draws a checkerboard on a :class:`DC`.
  
      :param `dc`: an instance of :class:`DC`;
      :param `rect`: the client rectangle on which to draw the checkerboard;
      :param `checkColour`: the colour used for the dark checkerboards;
      :param `box`: the checkerboards box sizes.
      
      :note: Used for the Alpha channel control and the colour panels.
      """
  
      y = rect.y
      checkPen = wx.Pen(checkColour)
      checkBrush = wx.Brush(checkColour)
  
      dc.SetPen(checkPen) 
      dc.SetBrush(checkBrush)
      dc.SetClippingRect(rect)
      
      while y < rect.height: 
          x = box*((y/box)%2) + 2
          while x < rect.width: 
              dc.DrawRectangle(x, y, box, box) 
              x += box*2 
          y += box
          
  
  
  class Colour(wx.Colour):
      """
      This is a subclass of :class:`Colour`, which adds Hue, Saturation and Brightness
      capability to the base class. It contains also methods to convert RGB triplets
      into HSB triplets and vice-versa.
      """
  
      def __init__(self, colour):
          """
          Default class constructor.
  
          :param `colour`: a standard :class:`Colour`.
          """
  
          wx.Colour.__init__(self)
  
          self.r = colour.Red()
          self.g = colour.Green()
          self.b = colour.Blue()
          self._alpha = colour.Alpha()
          
          self.ToHSV()
  
          
      def ToRGB(self):
          """ Converts a HSV triplet into a RGB triplet. """
      
          maxVal = self.v
          delta = (maxVal*self.s)/255.0
          minVal = maxVal - delta
  
          hue = float(self.h)
  
          if self.h > 300 or self.h <= 60:
          
              self.r = maxVal
              
              if self.h > 300:
              
                  self.g = int(minVal)
                  hue = (hue - 360.0)/60.0
                  self.b = int(-(hue*delta - minVal))
              
              else:
              
                  self.b = int(minVal)
                  hue = hue/60.0
                  self.g = int(hue*delta + minVal)
              
          elif self.h > 60 and self.h < 180:
          
              self.g = int(maxVal)
              
              if self.h < 120:
              
                  self.b = int(minVal)
                  hue = (hue/60.0 - 2.0)*delta
                  self.r = int(minVal - hue)
              
              else:
              
                  self.r = int(minVal)
                  hue = (hue/60.0 - 2.0)*delta
                  self.b = int(minVal + hue)
              
          
          else:
          
              self.b = int(maxVal)
              
              if self.h < 240:
              
                  self.r = int(minVal)
                  hue = (hue/60.0 - 4.0)*delta
                  self.g = int(minVal - hue)
              
              else:
              
                  self.g = int(minVal)
                  hue = (hue/60.0 - 4.0)*delta
                  self.r = int(minVal + hue)
          
  
      def ToHSV(self):
          """ Converts a RGB triplet into a HSV triplet. """
  
          minVal = float(min(self.r, min(self.g, self.b)))
          maxVal = float(max(self.r, max(self.g, self.b)))
          delta = maxVal - minVal
          
          self.v = int(maxVal)
          
          if abs(delta) < 1e-6:
          
              self.h = self.s = 0
          
          else:
          
              temp = delta/maxVal
              self.s = int(temp*255.0)
  
              if self.r == int(maxVal):
              
                  temp = float(self.g-self.b)/delta
              
              elif self.g == int(maxVal):
              
                  temp = 2.0 + (float(self.b-self.r)/delta)
              
              else:
              
                  temp = 4.0 + (float(self.r-self.g)/delta)
              
              temp *= 60
              if temp < 0:
              
                  temp += 360
              
              elif temp >= 360.0:
              
                  temp = 0
  
              self.h = int(temp)
  
  
      def GetPyColour(self):
          """ Returns the wxPython :class:`Colour` associated with this instance. """
  
          return wx.Colour(self.r, self.g, self.b, self._alpha)
  
      
          
  class LineDescription(object):
      """ Simple class to store description and constants for a line in 2D space. """
  
      def __init__(self, x=0, y=0, slope=None, c=None):
          """
          Default class constructor.
          
          Used internally. Do not call it in your code!
  
          :param `x`: the x coordinate of the first point;
          :param `y`: the y coordinate of the first point;
          :param `slope`: the line's slope;
          :param `c`: a floating point constant.        
          """
  
          self.x = x
          self.y = y
          self.slope = slope
          self.c = c
  
  
  class BasePyControl(wx.PyControl):
      """
      Base class used to hold common code for the HSB colour wheel and the RGB
      colour cube.
      """
  
      def __init__(self, parent, bitmap=None):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent;
          :param `bitmap`: the background bitmap for this custom control.
          """
  
          wx.PyControl.__init__(self, parent, style=wx.NO_BORDER)
          self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  
          self._bitmap = bitmap
          mask = wx.Mask(self._bitmap, wx.Colour(192, 192, 192))
          self._bitmap.SetMask(mask)
          
          self._mainDialog = wx.GetTopLevelParent(self)
  
          self.Bind(wx.EVT_SIZE, self.OnSize)
          self.Bind(wx.EVT_PAINT, self.OnPaint)
          self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
          self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
          self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
          self.Bind(wx.EVT_MOTION, self.OnMotion)
  
  
      def OnPaint(self, event):
          """
          Handles the ``wx.EVT_PAINT`` for :class:`BasePyControl`.
  
          :param `event`: a :class:`PaintEvent` event to be processed.
          """
  
          dc = wx.AutoBufferedPaintDC(self)
          dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
          
          dc.Clear()
          dc.DrawBitmap(self._bitmap, 0, 0, True)
  
          if self._mainDialog._initOver:
              self.DrawMarkers(dc)
          
  
      def OnEraseBackground(self, event):
          """
          Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`BasePyControl`.
  
          :param `event`: a :class:`EraseEvent` event to be processed.
  
          :note: This is intentionally empty to reduce flicker.        
          """
  
          pass
  
      
      def DrawMarkers(self, dc=None):
          """
          Draws the markers on top of the background bitmap.
  
          :param `dc`: an instance of :class:`DC`.
          
          :note: This method must be overridden in derived classes.
          """
  
          pass
  
  
      def DrawLines(self, dc):
          """
          Draws the lines connecting the markers on top of the background bitmap.
  
          :param `dc`: an instance of :class:`DC`.
          
          :note: This method must be overridden in derived classes.
          """
  
          pass
      
  
      def AcceptsFocusFromKeyboard(self):
          """
          Can this window be given focus by keyboard navigation? If not, the
          only way to give it focus (provided it accepts it at all) is to click
          it.
  
          :note: This method always returns ``False`` as we do not accept focus from
           the keyboard.
  
          :note: Overridden from :class:`PyControl`.
          """
  
          return False
  
  
      def AcceptsFocus(self):
          """
          Can this window be given focus by mouse click?
  
          :note: This method always returns ``False`` as we do not accept focus from
           mouse click.
  
          :note: Overridden from :class:`PyControl`.
          """
  
          return False
  
      
      def OnLeftDown(self, event):
          """
          Handles the ``wx.EVT_LEFT_DOWN`` for :class:`BasePyControl`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          
          :note: This method must be overridden in derived classes.
          """
  
          pass
  
  
      def OnLeftUp(self, event):
          """
          Handles the ``wx.EVT_LEFT_UP`` for :class:`BasePyControl`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          
          :note: This method must be overridden in derived classes.
          """
  
          pass
  
  
      def OnMotion(self, event):
          """
          Handles the ``wx.EVT_MOTION`` for :class:`BasePyControl`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          
          :note: This method must be overridden in derived classes.
          """
  
          pass
      
      
      def OnSize(self, event):
          """
          Handles the ``wx.EVT_SIZE`` for :class:`BasePyControl`.
  
          :param `event`: a :class:`SizeEvent` event to be processed.        
          """
  
          self.Refresh()
          
  
      def DoGetBestSize(self):
          """
          Overridden base class virtual. Determines the best size of the
          control based on the bitmap size.
  
          :note: Overridden from :class:`PyControl`.
          """
  
          return wx.Size(self._bitmap.GetWidth(), self._bitmap.GetHeight())        
  
          
  
  class RGBCube(BasePyControl):
      """
      Implements the drawing, mouse handling and sizing routines for the RGB
      cube colour.
      """
  
      def __init__(self, parent):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent window.        
          """
  
          BasePyControl.__init__(self, parent, bitmap=RGBCubeImage.GetBitmap())
          self._index = -1
  
  
      def DrawMarkers(self, dc=None):
          """
          Draws the markers on top of the background bitmap.
  
          :param `dc`: an instance of :class:`DC`.
          """
          
          if dc is None:
              dc = wx.ClientDC(self)
  
          oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
          dc.SetPen(wx.WHITE_PEN)
          dc.SetBrush(wx.TRANSPARENT_BRUSH)
          dc.SetLogicalFunction(wx.XOR)
  
          rects = []
          blueLen = self._mainDialog._blueLen
          greenLen = self._mainDialog._greenLen
          redLen = self._mainDialog._redLen
          colour = self._mainDialog._colour
  
          pt = [wx.Point() for i in xrange(3)]
          pt[0] = PointOnLine(Vertex, Top, (colour.r*redLen)/255, redLen)
          pt[1] = PointOnLine(Vertex, Left, (colour.g*greenLen)/255, greenLen)
          pt[2] = PointOnLine(Vertex, Right, (colour.b*blueLen)/255, blueLen)
  
          for i in xrange(3):
              rect = wx.Rect(pt[i].x - RECT_WIDTH, pt[i].y - RECT_WIDTH, 2*RECT_WIDTH, 2*RECT_WIDTH)
              rects.append(rect)
              dc.DrawRectangleRect(rect)
  
          self.DrawLines(dc)
          RestoreOldDC(dc, oldPen, oldBrush, oldMode)
  
          self._rects = rects
          
  
      def DrawLines(self, dc):
          """
          Draws the lines connecting the markers on top of the background bitmap.
  
          :param `dc`: an instance of :class:`DC`.
          """
          
          cuboid = self._mainDialog._cuboid
          
          dc.DrawLinePoint(cuboid[1], cuboid[2])
          dc.DrawLinePoint(cuboid[2], cuboid[3])
          dc.DrawLinePoint(cuboid[3], cuboid[4])
          dc.DrawLinePoint(cuboid[4], cuboid[5])
          dc.DrawLinePoint(cuboid[5], cuboid[2])
  
          dc.DrawLinePoint(cuboid[5], cuboid[6])
          dc.DrawLinePoint(cuboid[6], cuboid[7])
          dc.DrawLinePoint(cuboid[7], cuboid[4])
  
          dc.DrawLinePoint(cuboid[1], cuboid[6])
          
  
      def OnLeftDown(self, event):
          """
          Handles the ``wx.EVT_LEFT_DOWN`` for :class:`RGBCube`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
          
          point = wx.Point(event.GetX(), event.GetY())
          self._mouseIn = False
  
          if self._rects[RED].Contains(point):
              self.CaptureMouse()
              self._mouseIn = True
              self._index = RED
          
          elif self._rects[GREEN].Contains(point):
              self.CaptureMouse()
              self._mouseIn = True
              self._index = GREEN
          
          elif self._rects[BLUE].Contains(point):
              self.CaptureMouse()
              self._mouseIn = True
              self._index = BLUE
  
          
      def OnLeftUp(self, event):
          """
          Handles the ``wx.EVT_LEFT_UP`` for :class:`RGBCube`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
          
          if self.GetCapture():
              self.ReleaseMouse()
              self._mouseIn = False
          
  
      def OnMotion(self, event):
          """
          Handles the ``wx.EVT_MOTION`` for :class:`RGBCube`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
          
          point = wx.Point(event.GetX(), event.GetY())
          
          if not (self.GetCapture() and self._mouseIn):
              event.Skip()
              return
  
          bChange = False
          mainDialog = self._mainDialog
          colour = mainDialog._colour
          redLen, greenLen, blueLen = mainDialog._redLen, mainDialog._greenLen, mainDialog._blueLen
  
          dc = wx.ClientDC(self)
          self.DrawMarkers(dc)
          
          if self._index == RED:
          
              if point.y > Vertex.y:          
                  point.y = Vertex.y
              
              point.x = Vertex.x
              val = Distance(point, Vertex)
              if val > redLen:
                  val = redLen
              
              val = (float(val)/redLen)*255
              colour.r = int(val)
  
              pt = PointOnLine(Vertex, Top, (colour.r*redLen)/255, redLen)
              self._rects[RED] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
                                         2*RECT_WIDTH, 2*RECT_WIDTH)
  
              bChange = True
          
          elif self._index == GREEN:
          
              if point.x > Vertex.x:          
                  point.x = Vertex.x
              
              point.y = self._rects[GREEN].GetTop() + RECT_WIDTH
              val = Distance(point, Vertex)
              if val > greenLen:
                  val = greenLen
              
              val = (float(val)/greenLen)*255
              colour.g = int(val)
  
              pt = PointOnLine(Vertex, Left, (colour.g*greenLen)/255, greenLen)
              self._rects[GREEN] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
                                           2*RECT_WIDTH, 2*RECT_WIDTH)
  
              bChange = True
          
          elif self._index == BLUE:
          
              if point.x < Vertex.x:
                  point.x = Vertex.x
  
              point.y = self._rects[BLUE].GetTop() + RECT_WIDTH
              val = Distance(point, Vertex)
              if val > blueLen:
                  val = blueLen
              
              val = (float(val)/blueLen)*255
              colour.b = int(val)
  
              pt = PointOnLine(Vertex, Right, (colour.b*blueLen)/255, blueLen)
              self._rects[BLUE] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
                                          2*RECT_WIDTH, 2*RECT_WIDTH)
              
              bChange = True
          
          if bChange:
  
              mainDialog.CalcCuboid()
              self.DrawMarkers(dc)
          
              colour.ToHSV()
              mainDialog.SetSpinVals()
              mainDialog.CalcRects()
  
              mainDialog.DrawHSB()
              mainDialog.DrawBright()
              mainDialog.DrawAlpha()
          
      
  class HSVWheel(BasePyControl):
      """
      Implements the drawing, mouse handling and sizing routines for the HSV
      colour wheel.
      """
  
      def __init__(self, parent):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent window.
          """
  
          BasePyControl.__init__(self, parent, bitmap=HSVWheelImage.GetBitmap())
          self._mouseIn = False
  
  
      def DrawMarkers(self, dc=None):
          """
          Draws the markers on top of the background bitmap.
  
          :param `dc`: an instance of :class:`DC`.
          """
  
          if dc is None:
              dc = wx.ClientDC(self)
  
          oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
          dc.SetPen(wx.WHITE_PEN)
          dc.SetBrush(wx.TRANSPARENT_BRUSH)
          dc.SetLogicalFunction(wx.XOR)
          
          dc.DrawRectangleRect(self._mainDialog._currentRect)
          RestoreOldDC(dc, oldPen, oldBrush, oldMode)
          
  
      def OnLeftDown(self, event):
          """
          Handles the ``wx.EVT_LEFT_DOWN`` for :class:`HSVWheel`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
  
          point = wx.Point(event.GetX(), event.GetY())
          self._mouseIn = False
  
          if self.InCircle(point):
              self._mouseIn = True
  
          if self._mouseIn:
              self.CaptureMouse()
              self.TrackPoint(point)
  
  
      def OnLeftUp(self, event):
          """
          Handles the ``wx.EVT_LEFT_UP`` for :class:`HSVWheel`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
  
          if self.GetCapture():
              self.ReleaseMouse()
              self._mouseIn = False
  
  
      def OnMotion(self, event):
          """
          Handles the ``wx.EVT_MOTION`` for :class:`HSVWheel`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
  
          point = wx.Point(event.GetX(), event.GetY())
  
          if self.GetCapture() and self._mouseIn:
              self.TrackPoint(point)
          
  
      def InCircle(self, pt):
          """
          Returns whether a point is inside the HSV wheel or not.
  
          :param `pt`: an instance of :class:`Point`.
          """
  
          return Distance(pt, self._mainDialog._centre) <= RADIUS
  
  
      def TrackPoint(self, pt):
          """
          Track a mouse event inside the HSV colour wheel.
  
          :param `pt`: an instance of :class:`Point`.
          """
  
          if not self._mouseIn:
              return
  
          dc = wx.ClientDC(self)
          self.DrawMarkers(dc)
          mainDialog = self._mainDialog
          colour = mainDialog._colour
                  
          colour.h = int(rad2deg(AngleFromPoint(pt, mainDialog._centre)))
          if colour.h < 0:
              colour.h += 360
  
          colour.s = int(scaletomax(Distance(pt, mainDialog._centre)))
          if colour.s > 255:
              colour.s = 255
  
          mainDialog.CalcRects()
          self.DrawMarkers(dc)
          colour.ToRGB()
          mainDialog.SetSpinVals()
          
          mainDialog.CalcCuboid()
          mainDialog.DrawRGB()
          mainDialog.DrawBright()
          mainDialog.DrawAlpha()
  
  
  class BaseLineCtrl(wx.PyControl):
      """
      Base class used to hold common code for the Alpha channel control and the
      brightness palette control.
      """
  
      def __init__(self, parent):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent window.
          """
  
          wx.PyControl.__init__(self, parent, size=(20, 200), style=wx.NO_BORDER)
          self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)    
  
          self._mainDialog = wx.GetTopLevelParent(self)
          
          self.Bind(wx.EVT_SIZE, self.OnSize)
          self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
          self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
          self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
          self.Bind(wx.EVT_MOTION, self.OnMotion)
  
  
      def OnEraseBackground(self, event):
          """
          Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`BaseLineCtrl`.
  
          :param `event`: a :class:`EraseEvent` event to be processed.
  
          :note: This is intentionally empty to reduce flicker.        
          """
  
          pass
  
      
      def OnLeftDown(self, event):
          """
          Handles the ``wx.EVT_LEFT_DOWN`` for :class:`BaseLineCtrl`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
  
          point = wx.Point(event.GetX(), event.GetY())
          theRect = self.GetClientRect()
  
          if not theRect.Contains(point):
              event.Skip()
              return
          
          self.CaptureMouse()
          self.TrackPoint(point)
  
  
      def OnLeftUp(self, event):
          """
          Handles the ``wx.EVT_LEFT_UP`` for :class:`BaseLineCtrl`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
  
          if self.GetCapture():
              self.ReleaseMouse()
              
  
      def OnMotion(self, event):
          """
          Handles the ``wx.EVT_MOTION`` for :class:`BaseLineCtrl`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
  
          point = wx.Point(event.GetX(), event.GetY())
  
          if self.GetCapture():
              self.TrackPoint(point)
  
  
      def OnSize(self, event):
          """
          Handles the ``wx.EVT_SIZE`` for :class:`BaseLineCtrl`.
  
          :param `event`: a :class:`SizeEvent` event to be processed.
          """
  
          self.Refresh()
  
  
      def DoGetBestSize(self):
          """
          Overridden base class virtual. Determines the best size of the control.
  
          :note: Overridden from :class:`PyControl`.
          """
  
          return wx.Size(24, 208)    
  
  
      def BuildRect(self):
          """ Internal method. """
  
          brightRect = wx.Rect(*self.GetClientRect())
          brightRect.x += 2
          brightRect.y += 6
          brightRect.width -= 4
          brightRect.height -= 8
  
          return brightRect
  
  
      def AcceptsFocusFromKeyboard(self):
          """
          Can this window be given focus by keyboard navigation? If not, the
          only way to give it focus (provided it accepts it at all) is to click
          it.
  
          :note: This method always returns ``False`` as we do not accept focus from
           the keyboard.
  
          :note: Overridden from :class:`PyControl`.
          """
  
          return False
  
  
      def AcceptsFocus(self):
          """
          Can this window be given focus by mouse click? 
  
          :note: This method always returns ``False`` as we do not accept focus from
           mouse click.
  
          :note: Overridden from :class:`PyControl`.
          """
  
          return False
  
  
  
  class BrightCtrl(BaseLineCtrl):
      """
      Implements the drawing, mouse handling and sizing routines for the brightness
      palette control.
      """
  
      def __init__(self, parent):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent window.
          """
  
          BaseLineCtrl.__init__(self, parent)
          self.Bind(wx.EVT_PAINT, self.OnPaint)
  
          
      def OnPaint(self, event):
          """
          Handles the ``wx.EVT_PAINT`` for :class:`BrightCtrl`.
  
          :param `event`: a :class:`PaintEvent` event to be processed.
          """
  
          dc = wx.AutoBufferedPaintDC(self)
          dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
          dc.Clear()
          
          colour = self._mainDialog._colour.GetPyColour()
          brightRect = self.BuildRect()
          
          target_red = colour.Red()
          target_green = colour.Green()
          target_blue = colour.Blue()
  
          h, s, v = colorsys.rgb_to_hsv(target_red / 255.0, target_green / 255.0,
                                        target_blue / 255.0)
          v = 1.0
          vstep = 1.0/(brightRect.height-1)
          
          for y_pos in range(brightRect.y, brightRect.height+brightRect.y):
              r, g, b = [c * 255.0 for c in colorsys.hsv_to_rgb(h, s, v)]
              colour = wx.Colour(int(r), int(g), int(b))
              dc.SetPen(wx.Pen(colour, 1, wx.SOLID))
              dc.DrawRectangle(brightRect.x, y_pos, brightRect.width, 1)
              v = v - vstep
  
          dc.SetPen(wx.BLACK_PEN)
          dc.SetBrush(wx.TRANSPARENT_BRUSH)
          dc.DrawRectangleRect(brightRect)
          
          self.DrawMarkers(dc)
          
          
      def TrackPoint(self, pt):
          """
          Tracks a mouse action inside the palette control.
  
          :param `pt`: an instance of :class:`Point`.
          """
  
          brightRect = self.BuildRect()
          d = brightRect.GetBottom() - pt.y
          d *= 255
          d /= brightRect.height
          if d < 0:
             d = 0
          if d > 255:
              d = 255;
          
          mainDialog = self._mainDialog
          colour = mainDialog._colour
  
          mainDialog.DrawMarkers()        
          colour.v = int(d)
  
          colour.ToRGB()
          mainDialog.SetSpinVals()
  
          mainDialog.CalcRects()
          mainDialog.CalcCuboid()
          mainDialog.DrawMarkers()
          mainDialog.DrawAlpha()
  
  
      def DrawMarkers(self, dc=None):
          """
          Draws square markers used with mouse gestures.
  
          :param `dc`: an instance of :class:`DC`.
          """
  
          if dc is None:
              dc = wx.ClientDC(self)
              
          colour = self._mainDialog._colour
          brightRect = self.BuildRect()
          
          y = int(colour.v/255.0*brightRect.height)
          y = brightRect.GetBottom() - y
          brightMark = wx.Rect(brightRect.x-2, y-4, brightRect.width+4, 8)
  
          oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
          dc.SetPen(wx.Pen(wx.WHITE, 2))
          dc.SetBrush(wx.TRANSPARENT_BRUSH)
          dc.SetLogicalFunction(wx.XOR)
          
          dc.DrawRectangleRect(brightMark)
          RestoreOldDC(dc, oldPen, oldBrush, oldMode)
  
  
  class AlphaCtrl(BaseLineCtrl):
      """
      Implements the drawing, mouse handling and sizing routines for the alpha
      channel control. 
      """
  
      def __init__(self, parent):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent window.
          """
  
          BaseLineCtrl.__init__(self, parent)
          self.Bind(wx.EVT_PAINT, self.OnPaint)
  
  
      def OnPaint(self, event):
          """
          Handles the ``wx.EVT_PAINT`` for :class:`AlphaCtrl`.
  
          :param `event`: a :class:`PaintEvent` event to be processed.
          """
  
          pdc = wx.PaintDC(self)
          dc = wx.GCDC(pdc)
  
          mem_dc = wx.MemoryDC()
          fullRect = self.GetClientRect()
          bmp = wx.EmptyBitmap(fullRect.width, fullRect.height)
          mem_dc.SelectObject(bmp)
          
          rect = self.BuildRect()
          backBrush = wx.Brush(self.GetParent().GetBackgroundColour())
          mem_dc.SetBackground(backBrush)
          mem_dc.Clear()
  
          mem_dc.SetBrush(wx.WHITE_BRUSH)
          mem_dc.DrawRectangleRect(rect)
  
          DrawCheckerBoard(mem_dc, rect, checkColour)
          self.DrawAlphaShading(mem_dc, rect)
          mem_dc.DestroyClippingRegion()
          
          self.DrawMarkers(mem_dc)
          
          mem_dc.SetBrush(wx.TRANSPARENT_BRUSH)
          mem_dc.SetPen(wx.BLACK_PEN)
          mem_dc.DrawRectangleRect(rect)
  
          mem_dc.SelectObject(wx.NullBitmap)
          pdc.DrawBitmap(bmp, 0, 0)
          
  
      def DrawAlphaShading(self, dc, rect):
          """
          Draws the alpha shading on top of the checkerboard.
  
          :param `dc`: an instance of :class:`DC`;
          :param `rect`: the :class:`AlphaCtrl` client rectangle.
          """
  
          gcdc = wx.GCDC(dc)
          
          colour = self._mainDialog._colour.GetPyColour()
          
          alpha = 255.0
          vstep = 255.0*2/(rect.height-1)
          r, g, b = colour.Red(), colour.Green(), colour.Blue()
  
          colour_gcdc = wx.Colour(r, g, b, alpha)
          gcdc.SetBrush(wx.TRANSPARENT_BRUSH)
          
          for y_pos in range(rect.y, rect.height+rect.y, 2):
              colour_gcdc = wx.Colour(r, g, b, int(alpha))
              gcdc.SetPen(wx.Pen(colour_gcdc, 1, wx.SOLID))
              gcdc.DrawRectangle(rect.x, y_pos, rect.width, 2)
              alpha = alpha - vstep
  
  
      def TrackPoint(self, pt):
          """
          Tracks a mouse action inside the Alpha channel control.
  
          :param `pt`: an instance of :class:`Point`.            
          """
  
          alphaRect = self.BuildRect()
          d = alphaRect.GetBottom() - pt.y
          d *= 255
          d /= alphaRect.height
          if d < 0:
             d = 0
          if d > 255:
              d = 255
  
          self._mainDialog._colour._alpha = int(d)
          self.Refresh()
          self._mainDialog.SetSpinVals()
  
  
      def DrawMarkers(self, dc=None):
          """
          Draws square markers used with mouse gestures.
  
          :param `dc`: an instance of :class:`DC`.
          """
  
          if dc is None:
              dc = wx.ClientDC(self)
              
          colour = self._mainDialog._colour
          alphaRect = self.BuildRect()
          
          y = int(colour._alpha/255.0*alphaRect.height)
          y = alphaRect.GetBottom() - y
          alphaMark = wx.Rect(alphaRect.x-2, y-4, alphaRect.width+4, 8)
  
          oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
          dc.SetPen(wx.Pen(wx.WHITE, 2))
          dc.SetBrush(wx.TRANSPARENT_BRUSH)
          dc.SetLogicalFunction(wx.XOR)
          
          dc.DrawRectangleRect(alphaMark)
          RestoreOldDC(dc, oldPen, oldBrush, oldMode)
          
          
  class ColourPanel(wx.PyPanel):
      """
      Simple custom class used to display "old" and "new" colour panels, with alpha
      blending capabilities.
      """
  
      def __init__(self, parent, style=wx.SIMPLE_BORDER):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent window;
          :param `style`: the :class:`ColourPanel` window style.
          """
  
          wx.PyPanel.__init__(self, parent, style=style)
          self._mainDialog = wx.GetTopLevelParent(self)
          
          self.Bind(wx.EVT_PAINT, self.OnPaint)
          self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
          self.Bind(wx.EVT_SIZE, self.OnSize)
  
          self._colour = Colour(wx.WHITE)
          
  
      def OnPaint(self, event):
          """
          Handles the ``wx.EVT_PAINT`` for :class:`ColourPanel`.
  
          :param `event`: a :class:`PaintEvent` event to be processed.
          """
  
          pdc = wx.PaintDC(self)
          dc = wx.GCDC(pdc)
  
          mem_dc = wx.MemoryDC()
          rect = self.GetClientRect()
          bmp = wx.EmptyBitmap(rect.width, rect.height)
          mem_dc.SelectObject(bmp)
          
          backBrush = wx.Brush(self.GetParent().GetBackgroundColour())
          mem_dc.SetBackground(backBrush)
          mem_dc.Clear()
  
          mem_dc.SetBrush(wx.WHITE_BRUSH)
          mem_dc.DrawRectangleRect(rect)
  
          DrawCheckerBoard(mem_dc, rect, checkColour, box=10)
  
          gcdc = wx.GCDC(mem_dc)
          colour_gcdc = wx.Colour(self._colour.r, self._colour.g, self._colour.b, self._colour._alpha)
          gcdc.SetBrush(wx.Brush(colour_gcdc))
          gcdc.SetPen(wx.Pen(colour_gcdc))
          gcdc.DrawRectangleRect(rect)
  
          mem_dc.SelectObject(wx.NullBitmap)
          dc.DrawBitmap(bmp, 0, 0)
  
  
      def OnEraseBackground(self, event):
          """
          Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`ColourPanel`.
  
          :param `event`: a :class:`EraseEvent` event to be processed.
  
          :note: This is intentionally empty to reduce flicker.        
          """
  
          pass
      
  
      def OnSize(self, event):
          """
          Handles the ``wx.EVT_SIZE`` for :class:`ColourPanel`.
  
          :param `event`: a :class:`SizeEvent` event to be processed.
          """
  
          self.Refresh()
  
          
      def RefreshColour(self, colour):
          """
          Refresh the panel after a colour/alpha change.
  
          :param `colour`: the new background colour of :class:`ColourPanel`.
          """
  
          self._colour = colour
          self.Refresh()
          
          
      def AcceptsFocusFromKeyboard(self):
          """
          Can this window be given focus by keyboard navigation? If not, the
          only way to give it focus (provided it accepts it at all) is to click
          it.
  
          :note: This method always returns ``False`` as we do not accept focus from
           the keyboard.
  
          :note: Overridden from :class:`PyPanel`.
          """
  
          return False
  
  
      def AcceptsFocus(self):
          """
          Can this window be given focus by mouse click?
  
          :note: This method always returns ``False`` as we do not accept focus from
           mouse click.
  
          :note: Overridden from :class:`PyPanel`.
          """
  
          return False
  
  
  class CustomPanel(wx.PyControl):
      """
      This panel displays a series of custom colours (chosen by the user) just like
      the standard :class:`ColourDialog`.
      """
  
      def __init__(self, parent, colourData):
          """
          Default class constructor.
          Used internally. Do not call it in your code!
  
          :param `parent`: the control parent window;
          :param `colourData`: an instance of :class:`ColourData`.
          """
          
          wx.PyControl.__init__(self, parent, style=wx.NO_BORDER)
          self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  
          self._colourData = colourData
          self._customColours = [None]*16
          self._mainDialog = wx.GetTopLevelParent(self)
          
          self.InitializeColours()
  
          self._smallRectangleSize = wx.Size(20, 16)
          self._gridSpacing = 4
          self._customColourRect = wx.Rect(2, 2, (8*self._smallRectangleSize.x) + (7*self._gridSpacing),
                                           (2*self._smallRectangleSize.y) + (1*self._gridSpacing))
  
          self.Bind(wx.EVT_PAINT, self.OnPaint)
          self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
          self.Bind(wx.EVT_SIZE, self.OnSize)
          self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
          
  
      def InitializeColours(self):
          """ Initializes the 16 custom colours in :class:`CustomPanel`. """
  
          curr = self._colourData.GetColour()
          self._colourSelection = -1
          
          for i in xrange(16):
              c = self._colourData.GetCustomColour(i)
              if c.Ok():
                  self._customColours[i] = self._colourData.GetCustomColour(i)
              else:
                  self._customColours[i] = wx.Colour(255, 255, 255)
  
              if c == curr:
                  self._colourSelection = i
  
  
      def DoGetBestSize(self):
          """
          Overridden base class virtual. Determines the best size of the control.
  
          :note: Overridden from :class:`PyControl`.
          """
  
          return self._customColourRect.width+4, self._customColourRect.height+4
  
  
      def OnPaint(self, event):
          """
          Handles the ``wx.EVT_PAINT`` for :class:`CustomPanel`.
  
          :param `event`: a :class:`PaintEvent` event to be processed.
          """
  
          dc = wx.AutoBufferedPaintDC(self)
          dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
          dc.Clear()
  
          self.PaintCustomColours(dc)
          self.PaintHighlight(dc, True)
  
  
      def OnEraseBackground(self, event):
          """
          Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`CustomPanel`.
  
          :param `event`: a :class:`EraseEvent` event to be processed.
  
          :note: This is intentionally empty to reduce flicker.        
          """
  
          pass
  
  
      def OnSize(self, event):
          """
          Handles the ``wx.EVT_SIZE`` for :class:`CustomPanel`.
  
          :param `event`: a :class:`SizeEvent` event to be processed.        
          """
  
          self.Refresh()
          
  
      def OnLeftDown(self, event):
          """
          Handles the ``wx.EVT_LEFT_DOWN`` for :class:`CustomPanel`.
  
          :param `event`: a :class:`MouseEvent` event to be processed.
          """
  
          x, y = event.GetX(), event.GetY()
          
          selX = (x - self._customColourRect.x)/(self._smallRectangleSize.x + self._gridSpacing)
          selY = (y - self._customColourRect.y)/(self._smallRectangleSize.y + self._gridSpacing)
          ptr = selX + selY*8
  
          dc = wx.ClientDC(self)
          self.PaintHighlight(dc, False)
          self._colourSelection = ptr
  
          self._mainDialog._colour = Colour(self._customColours[self._colourSelection])
          
          self.PaintCustomColour(dc, selX, selY)
          self.PaintHighlight(dc, True)
          self._mainDialog.DrawAll()
  
  
      def PaintCustomColours(self, dc):
          """
          Draws all the 16 subpanels with their custom colours.
  
          :param `dc`: an instance of :class:`DC`.
          """
  
          for i in xrange(2):
              for j in xrange(8):
              
                  ptr = i*8 + j
                  x = (j*(self._smallRectangleSize.x+self._gridSpacing)) + self._customColourRect.x
                  y = (i*(self._smallRectangleSize.y+self._gridSpacing)) + self._customColourRect.y
  
                  dc.SetPen(wx.BLACK_PEN)
  
                  brush = wx.Brush(self._customColours[ptr])
                  dc.SetBrush(brush)
  
                  dc.DrawRectangle(x, y, self._smallRectangleSize.x, self._smallRectangleSize.y)
      
  
      def PaintHighlight(self, dc, draw=True):
          """
          Highlight the current custom colour selection (if any).
  
          :param `dc`: an instance of :class:`DC`;
          :param `draw`: whether to draw a thin black border around the selected custom
           colour or not.
          """
  
          if self._colourSelection < 0:
              return
  
          # Number of pixels bigger than the standard rectangle size
          # for drawing a highlight
          deltaX = deltaY = 2
  
          # User-defined colours
          y = self._colourSelection/8
          x = self._colourSelection - (y*8)
  
          x = (x*(self._smallRectangleSize.x + self._gridSpacing) + self._customColourRect.x) - deltaX
          y = (y*(self._smallRectangleSize.y + self._gridSpacing) + self._customColourRect.y) - deltaY
  
          if draw:
              dc.SetPen(wx.BLACK_PEN)
          else:
              dc.SetPen(wx.LIGHT_GREY_PEN)
  
          dc.SetBrush(wx.TRANSPARENT_BRUSH)
          dc.DrawRectangle(x, y, (self._smallRectangleSize.x + (2*deltaX)), (self._smallRectangleSize.y + (2*deltaY)))
  
  
      def PaintCustomColour(self, dc, selX, selY):
          """
          Paints a newly added custom colour subpanel.
  
          :param `dc`: an instance of :class:`DC`;
          :param `selX`: the x coordinate of the custom colour subpanel;
          :param `selY`: the y coordinate of the custom colour subpanel.        
          """
  
          dc.SetPen(wx.BLACK_PEN)
  
          brush = wx.Brush(self._customColours[self._colourSelection])
          dc.SetBrush(brush)
  
          ptr = selX*8 + selY
          x = (selX*(self._smallRectangleSize.x+self._gridSpacing)) + self._customColourRect.x
          y = (selY*(self._smallRectangleSize.y+self._gridSpacing)) + self._customColourRect.y
  
          dc.DrawRectangle(x, y, self._smallRectangleSize.x, self._smallRectangleSize.y)
  
          dc.SetBrush(wx.NullBrush)
  
  
      def AddCustom(self, colour):
          """
          Adds a user-chosen colour to the list of custom colours.
  
          :param `colour`: an instance of :class:`Colour`.
          """
  
          self._colourSelection += 1
          self._colourSelection = self._colourSelection%16
              
          dc = wx.ClientDC(self)
          self._customColours[self._colourSelection] = colour.GetPyColour()
          self._colourData.SetCustomColour(self._colourSelection, self._customColours[self._colourSelection])
  
          self.PaintCustomColours(dc)
          
  
  class CubeColourDialog(wx.Dialog):
      """
      This is the CubeColourDialog main class implementation.
      """
  
      def __init__(self, parent, colourData=None, agwStyle=CCD_SHOW_ALPHA):
          """
          Default class constructor.
  
          :param `colourData`: a standard :class:`ColourData` (as used in :class:`ColourDialog`);
          :param `agwStyle`: can be either ``None`` or ``CCD_SHOW_ALPHA``, depending if you want
           to hide the alpha channel control or not.
          """
  
          wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=_("CubeColourDialog: Choose Colour"),
                             pos=wx.DefaultPosition, size=(900, 900), style=wx.DEFAULT_DIALOG_STYLE)
  
          if colourData:
              self._colourData = colourData
          else:
              self._colourData = wx.ColourData()
              self._colourData.SetColour(wx.Colour(128, 128, 128))
  
          self._colour = Colour(self._colourData.GetColour())
          self._oldColour = Colour(self._colourData.GetColour())
          
          self._inMouse = False
          self._initOver = False
          self._inDrawAll = False
          self._agwStyle = agwStyle
  
          self.mainPanel = wx.Panel(self, -1)
  
          self.hsvSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("HSB"))
          self.rgbValueSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("RGB Values"))
          self.hsvValueSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("HSB Values"))
          self.rgbSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("RGB"))
          self.alphaSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("Alpha"))
          self.alphaValueSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("Alpha"))
  
          self.rgbBitmap = RGBCube(self.mainPanel)
          self.hsvBitmap = HSVWheel(self.mainPanel)
          self.brightCtrl = BrightCtrl(self.mainPanel)
          self.alphaCtrl = AlphaCtrl(self.mainPanel)
  
          self.showAlpha = wx.CheckBox(self.mainPanel, -1, _("Show Alpha Control"))
          self.customColours = CustomPanel(self.mainPanel, self._colourData)
          self.addCustom = wx.Button(self.mainPanel, -1, _("Add to custom colours"))
          
          self.okButton = wx.Button(self.mainPanel, -1, _("OK"))
          self.cancelButton = wx.Button(self.mainPanel, -1, _("Cancel"))
  
          self.oldColourPanel = ColourPanel(self.mainPanel, style=wx.SIMPLE_BORDER)
          self.newColourPanel = ColourPanel(self.mainPanel, style=wx.SIMPLE_BORDER)
          
          self.redSpin = wx.SpinCtrl(self.mainPanel, -1, "180", min=0, max=255,
                                     style=wx.SP_ARROW_KEYS)
          self.greenSpin = wx.SpinCtrl(self.mainPanel, -1, "180", min=0, max=255,
                                       style=wx.SP_ARROW_KEYS)
          self.blueSpin = wx.SpinCtrl(self.mainPanel, -1, "180", min=0, max=255,
                                      style=wx.SP_ARROW_KEYS)
          self.hueSpin = wx.SpinCtrl(self.mainPanel, -1, "0", min=0, max=359,
                                     style=wx.SP_ARROW_KEYS)
          self.saturationSpin = wx.SpinCtrl(self.mainPanel, -1, "", min=0, max=255,
                                            style=wx.SP_ARROW_KEYS)
          self.brightnessSpin = wx.SpinCtrl(self.mainPanel, -1, "", min=0, max=255,
                                            style=wx.SP_ARROW_KEYS)
          self.alphaSpin = wx.SpinCtrl(self.mainPanel, -1, "", min=0, max=255,
                                       style=wx.SP_ARROW_KEYS)
          self.accessCode = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
          self.htmlCode = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
          self.webSafe = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
          self.htmlName = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
          
          self.SetProperties()
          self.DoLayout()
  
          self.spinCtrls = [self.redSpin, self.greenSpin, self.blueSpin,
                            self.hueSpin, self.saturationSpin, self.brightnessSpin]
  
          for spin in self.spinCtrls:
              spin.Bind(wx.EVT_SPINCTRL, self.OnSpinCtrl)
  
          self.Bind(wx.EVT_SPINCTRL, self.OnAlphaSpin, self.alphaSpin)
          
          self.Bind(wx.EVT_BUTTON, self.OnOk, self.okButton)
          self.Bind(wx.EVT_BUTTON, self.OnCancel, self.cancelButton)
          self.Bind(wx.EVT_BUTTON, self.OnAddCustom, self.addCustom)
  
          self.Bind(wx.EVT_CHECKBOX, self.OnShowAlpha)
          self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
          self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyUp)
  
          self.Centre(wx.BOTH)
  
          wx.CallAfter(self.InitDialog)
          
          
      def SetProperties(self):
          """ Sets some initial properties for :class:`CubeColourDialog` (sizes, values). """
  
          self.okButton.SetDefault()
          self.oldColourPanel.SetMinSize((-1, 50))
          self.newColourPanel.SetMinSize((-1, 50))
          self.redSpin.SetMinSize((60, -1))
          self.greenSpin.SetMinSize((60, -1))
          self.blueSpin.SetMinSize((60, -1))
          self.hueSpin.SetMinSize((60, -1))
          self.saturationSpin.SetMinSize((60, -1))
          self.brightnessSpin.SetMinSize((60, -1))
          self.alphaSpin.SetMinSize((60, -1))
          self.showAlpha.SetValue(1)
          self.accessCode.SetInitialSize((80, -1))
          self.webSafe.SetInitialSize((80, -1))
          self.htmlCode.SetInitialSize((80, -1))
  
  
      def DoLayout(self):
          """ Layouts all the controls in the :class:`CubeColourDialog`. """
  
          dialogSizer = wx.BoxSizer(wx.VERTICAL)
          mainSizer = wx.GridBagSizer(10, 5)
          hsvValueSizer = wx.StaticBoxSizer(self.hsvValueSizer_staticbox, wx.VERTICAL)
          hsvGridSizer = wx.GridSizer(2, 3, 2, 10)
          rgbValueSizer = wx.StaticBoxSizer(self.rgbValueSizer_staticbox, wx.HORIZONTAL)
          rgbGridSizer = wx.GridSizer(2, 3, 2, 10)
          alphaValueSizer = wx.StaticBoxSizer(self.alphaValueSizer_staticbox, wx.VERTICAL)
          alphaGridSizer = wx.BoxSizer(wx.VERTICAL)
          customSizer = wx.BoxSizer(wx.VERTICAL)
          buttonSizer = wx.BoxSizer(wx.VERTICAL)
          accessSizer = wx.BoxSizer(wx.VERTICAL)
          panelSizer = wx.BoxSizer(wx.VERTICAL)
          htmlSizer1 = wx.BoxSizer(wx.HORIZONTAL)
          htmlSizer2 = wx.BoxSizer(wx.VERTICAL)
          htmlSizer_a = wx.BoxSizer(wx.VERTICAL)
          htmlSizer_b = wx.BoxSizer(wx.VERTICAL)
          
          hsvSizer = wx.StaticBoxSizer(self.hsvSizer_staticbox, wx.HORIZONTAL)
          rgbSizer = wx.StaticBoxSizer(self.rgbSizer_staticbox, wx.VERTICAL)
          alphaSizer = wx.StaticBoxSizer(self.alphaSizer_staticbox, wx.VERTICAL)
  
          mainSizer.Add(self.showAlpha, (0, 0), (1, 1), wx.LEFT|wx.TOP, 10)
  
          htmlLabel1 = wx.StaticText(self.mainPanel, -1, _("HTML Code"))
          htmlLabel2 = wx.StaticText(self.mainPanel, -1, _("Web Safe"))
          htmlSizer_a.Add(htmlLabel1, 0, wx.TOP, 3)
          htmlSizer_b.Add(htmlLabel2, 0, wx.TOP, 3)
          htmlSizer_a.Add(self.htmlCode, 0, wx.TOP, 3)
          htmlSizer_b.Add(self.webSafe, 0, wx.TOP, 3)
  
          htmlSizer1.Add(htmlSizer_a, 0)
          htmlSizer1.Add(htmlSizer_b, 0, wx.LEFT, 10)
          mainSizer.Add(htmlSizer1, (1, 0), (1, 1), wx.LEFT|wx.RIGHT, 10)
          
          htmlLabel3 = wx.StaticText(self.mainPanel, -1, _("HTML Name"))
          htmlSizer2.Add(htmlLabel3, 0, wx.TOP|wx.BOTTOM, 3)
          htmlSizer2.Add(self.htmlName, 0)
          
          mainSizer.Add(htmlSizer2, (1, 1), (1, 1), wx.LEFT|wx.RIGHT, 10)
  
          customLabel = wx.StaticText(self.mainPanel, -1, _("Custom Colours"))
          customSizer.Add(customLabel, 0, wx.BOTTOM, 3)
          customSizer.Add(self.customColours, 0)
          customSizer.Add(self.addCustom, 0, wx.TOP|wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, 5)
          mainSizer.Add(customSizer, (0, 2), (2, 2), wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
  
          rgbSizer.Add(self.rgbBitmap, 0, wx.ALL, 15)
          mainSizer.Add(rgbSizer, (2, 0), (1, 1), wx.ALL|wx.EXPAND, 10)
          hsvSizer.Add(self.hsvBitmap, 0, wx.ALL, 15)
          hsvSizer.Add(self.brightCtrl, 0, wx.RIGHT|wx.TOP|wx.BOTTOM, 15)
          mainSizer.Add(hsvSizer, (2, 1), (1, 1), wx.ALL|wx.EXPAND, 10)
          alphaSizer.Add(self.alphaCtrl, 0, wx.TOP|wx.ALIGN_CENTER, 15)
          mainSizer.Add(alphaSizer, (2, 2), (1, 1), wx.ALL|wx.EXPAND, 10)
          
          oldLabel = wx.StaticText(self.mainPanel, -1, _("Old Colour"))
          panelSizer.Add(oldLabel, 0, wx.BOTTOM, 3)
          panelSizer.Add(self.oldColourPanel, 0, wx.BOTTOM|wx.EXPAND, 20)
          newLabel = wx.StaticText(self.mainPanel, -1, _("New Colour"))
          accessLabel = wx.StaticText(self.mainPanel, -1, _("MS Access Code"))
          accessSizer.Add(accessLabel, 0, wx.BOTTOM, 3)
          accessSizer.Add(self.accessCode, 0)
          panelSizer.Add(newLabel, 0, wx.BOTTOM, 3)
          panelSizer.Add(self.newColourPanel, 0, wx.EXPAND)
          panelSizer.Add((0, 0), 1, wx.EXPAND)
          panelSizer.Add(accessSizer, 0, wx.TOP, 5)
          mainSizer.Add(panelSizer, (2, 3), (1, 1), wx.ALL|wx.EXPAND, 10)
          redLabel = wx.StaticText(self.mainPanel, -1, _("Red"))
          rgbGridSizer.Add(redLabel, 0)
          greenLabel = wx.StaticText(self.mainPanel, -1, _("Green"))
          rgbGridSizer.Add(greenLabel, 0)
          blueLabel = wx.StaticText(self.mainPanel, -1, _("Blue"))
          rgbGridSizer.Add(blueLabel, 0)
          rgbGridSizer.Add(self.redSpin, 0, wx.EXPAND)
          rgbGridSizer.Add(self.greenSpin, 0, wx.EXPAND)
          rgbGridSizer.Add(self.blueSpin, 0, wx.EXPAND)
          rgbValueSizer.Add(rgbGridSizer, 1, 0, 0)
          mainSizer.Add(rgbValueSizer, (3, 0), (1, 1), wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 10)
          hueLabel = wx.StaticText(self.mainPanel, -1, _("Hue"))
          hsvGridSizer.Add(hueLabel, 0)
          saturationLabel = wx.StaticText(self.mainPanel, -1, _("Saturation"))
          hsvGridSizer.Add(saturationLabel, 0)
          brightnessLabel = wx.StaticText(self.mainPanel, -1, _("Brightness"))
          hsvGridSizer.Add(brightnessLabel, 0)
          hsvGridSizer.Add(self.hueSpin, 0, wx.EXPAND)
          hsvGridSizer.Add(self.saturationSpin, 0, wx.EXPAND)
          hsvGridSizer.Add(self.brightnessSpin, 0, wx.EXPAND)
          hsvValueSizer.Add(hsvGridSizer, 1, wx.EXPAND)
          mainSizer.Add(hsvValueSizer, (3, 1), (1, 1), wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 10)
          alphaLabel = wx.StaticText(self.mainPanel, -1, _("Alpha"))
          alphaGridSizer.Add(alphaLabel, 0)
          alphaGridSizer.Add(self.alphaSpin, 0, wx.EXPAND|wx.TOP, 10)
          alphaValueSizer.Add(alphaGridSizer, 1, wx.EXPAND)
          mainSizer.Add(alphaValueSizer, (3, 2), (1, 1), wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 10)
          buttonSizer.Add(self.okButton, 0, wx.BOTTOM, 3)
          buttonSizer.Add(self.cancelButton, 0)
          mainSizer.Add(buttonSizer, (3, 3), (1, 1), wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
  
          self.mainPanel.SetAutoLayout(True)
          self.mainPanel.SetSizer(mainSizer)
          mainSizer.Fit(self.mainPanel)
          mainSizer.SetSizeHints(self.mainPanel)
  
          if self.GetAGWWindowStyleFlag() & CCD_SHOW_ALPHA == 0:
              mainSizer.Hide(self.showAlpha)
              mainSizer.Hide(alphaSizer)
              mainSizer.Hide(alphaValueSizer)
          
          dialogSizer.Add(self.mainPanel, 1, wx.EXPAND)
          self.SetAutoLayout(True)
          self.SetSizer(dialogSizer)
          dialogSizer.Fit(self)
          dialogSizer.SetSizeHints(self)
          self.Layout()
  
          self.mainSizer = mainSizer
          self.dialogSizer = dialogSizer
          self.alphaSizers = [alphaSizer, alphaValueSizer]
          
  
      def InitDialog(self):
          """ Initialize the :class:`CubeColourDialog`. """
  
          hsvRect = self.hsvBitmap.GetClientRect()
          self._centre = wx.Point(hsvRect.x + hsvRect.width/2, hsvRect.y + hsvRect.height/2)
  
          self._redLen = Distance(Vertex, Top)
          self._greenLen = Distance(Vertex, Left)
          self._blueLen = Distance(Vertex, Right)
  
          self.CalcSlopes()
          self.CalcCuboid()
          self.CalcRects()
  
          self.SetSpinVals()
  
          self._initOver = True
          wx.CallAfter(self.Refresh)
                          
  
      def CalcSlopes(self):
          """ Calculates the line slopes in the RGB colour cube. """
  
          self._lines = {RED: LineDescription(), GREEN: LineDescription(), BLUE: LineDescription}
          
          self._lines[RED].slope = Slope(Top, Vertex)
          self._lines[GREEN].slope = Slope(Left, Vertex)
          self._lines[BLUE].slope = Slope(Right, Vertex)
  
          for i in xrange(3):
              self._lines[i].x = Vertex.x
              self._lines[i].y = Vertex.y
              self._lines[i].c = FindC(self._lines[i])
  
  
      def CalcCuboid(self):
          """ Calculates the RGB colour cube vertices. """
  
          rLen = (self._colour.r*self._redLen)/255.0
          gLen = (self._colour.g*self._greenLen)/255.0
          bLen = (self._colour.b*self._blueLen)/255.0
  
          lines = [LineDescription() for i in xrange(12)]
          self._cuboid = [None]*8
  
          self._cuboid[0] = Vertex
          self._cuboid[1] = PointOnLine(Vertex, Top, int(rLen), self._redLen)
          self._cuboid[3] = PointOnLine(Vertex, Left, int(gLen), self._greenLen)
          self._cuboid[7] = PointOnLine(Vertex, Right, int(bLen), self._blueLen)
  
          lines[0] = self._lines[RED]
          lines[1] = self._lines[GREEN]
          lines[2] = self._lines[BLUE]
  
          lines[3].slope = self._lines[GREEN].slope
          lines[3].x = self._cuboid[1].x
          lines[3].y = self._cuboid[1].y
          lines[3].c = FindC(lines[3])
  
          lines[4].slope = self._lines[RED].slope
          lines[4].x = self._cuboid[3].x
          lines[4].y = self._cuboid[3].y
          lines[4].c = FindC(lines[4])
  
          lines[5].slope = self._lines[BLUE].slope
          lines[5].x = self._cuboid[3].x
          lines[5].y = self._cuboid[3].y
          lines[5].c = FindC(lines[5])
  
          lines[6].slope = self._lines[GREEN].slope
          lines[6].x = self._cuboid[7].x
          lines[6].y = self._cuboid[7].y
          lines[6].c = FindC(lines[6])
  
          lines[10].slope = self._lines[BLUE].slope
          lines[10].x = self._cuboid[1].x
          lines[10].y = self._cuboid[1].y
          lines[10].c = FindC(lines[10])
  
          lines[11].slope = self._lines[RED].slope
          lines[11].x = self._cuboid[7].x
          lines[11].y = self._cuboid[7].y
          lines[11].c = FindC(lines[11])
  
          self._cuboid[2] = Intersection(lines[3], lines[4])
          self._cuboid[4] = Intersection(lines[5], lines[6])
          self._cuboid[6] = Intersection(lines[10], lines[11])
  
          lines[7].slope = self._lines[RED].slope
          lines[7].x = self._cuboid[4].x
          lines[7].y = self._cuboid[4].y
          lines[7].c = FindC(lines[7])
  
          lines[8].slope = self._lines[BLUE].slope
          lines[8].x = self._cuboid[2].x
          lines[8].y = self._cuboid[2].y
          lines[8].c = FindC(lines[8])
  
          self._cuboid[5] = Intersection(lines[7], lines[8])
                  
  
      def CalcRects(self):
          """ Calculates the brightness control user-selected rect. """
  
          pt = PtFromAngle(self._colour.h, self._colour.s, self._centre)
          self._currentRect = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
                                      2*RECT_WIDTH, 2*RECT_WIDTH)
  
  
      def DrawMarkers(self, dc=None):
          """
          Draws the markers for all the controls.
  
          :param `dc`: an instance of :class:`DC`. If `dc` is ``None``, a :class:`ClientDC` is
           created on the fly.
          """
  
          if dc is None:
              dc = wx.ClientDC(self)
  
          self.hsvBitmap.DrawMarkers()
          self.rgbBitmap.DrawMarkers()
          self.brightCtrl.DrawMarkers()
          
  
      def DrawRGB(self):
          """ Refreshes the RGB colour cube. """
  
          self.rgbBitmap.Refresh()
  
  
      def DrawHSB(self):
          """ Refreshes the HSB colour wheel. """
  
          self.hsvBitmap.Refresh()
          
  
      def DrawBright(self):
          """ Refreshes the brightness control. """
  
          self.brightCtrl.Refresh()
  
  
      def DrawAlpha(self):
          """ Refreshes the alpha channel control. """
  
          self.alphaCtrl.Refresh()        
          
          
      def SetSpinVals(self):
          """ Sets the values for all the spin controls. """
  
          self.redSpin.SetValue(self._colour.r)
          self.greenSpin.SetValue(self._colour.g)
          self.blueSpin.SetValue(self._colour.b)
          
          self.hueSpin.SetValue(self._colour.h)
          self.saturationSpin.SetValue(self._colour.s)
          self.brightnessSpin.SetValue(self._colour.v)
  
          self.alphaSpin.SetValue(self._colour._alpha)        
  
          self.SetPanelColours()
          self.SetCodes()
          
  
      def SetPanelColours(self):
          """ Assigns colours to the colour panels. """
  
          self.oldColourPanel.RefreshColour(self._oldColour)
          self.newColourPanel.RefreshColour(self._colour)
          
  
      def SetCodes(self):
          """ Sets the HTML/MS Access codes (if any) in the text controls. """
  
          colour = rgb2html(self._colour)
          self.htmlCode.SetValue(colour)
          self.htmlCode.Refresh()
  
          if colour in HTMLCodes:
              colourName, access, webSafe = HTMLCodes[colour]
              self.webSafe.SetValue(webSafe)
              self.accessCode.SetValue(access)
              self.htmlName.SetValue(colourName)
          else:
              self.webSafe.SetValue("")
              self.accessCode.SetValue("")
              self.htmlName.SetValue("")
          
          
      def OnCloseWindow(self, event):
          """
          Handles the ``wx.EVT_CLOSE`` event for :class:`CubeColourDialog`.
          
          :param `event`: a :class:`CloseEvent` event to be processed.
          """
  
          self.EndModal(wx.ID_CANCEL)
  
  
      def OnKeyUp(self, event):
          """
          Handles the ``wx.EVT_CHAR_HOOK`` event for :class:`CubeColourDialog`.
          
          :param `event`: a :class:`KeyEvent` event to be processed.
          """
  
          if event.GetKeyCode() == wx.WXK_ESCAPE:
              self.EndModal(wx.ID_CANCEL)
  
          event.Skip()
          
  
      def ShowModal(self):
          """
          Shows :class:`CubeColourDialog` as a modal dialog. Program flow does
          not return until the dialog has been dismissed with `EndModal`.
  
          :note: Overridden from :class:`Dialog`. 
          """
  
          return wx.Dialog.ShowModal(self)
  
  
      def SetAGWWindowStyleFlag(self, agwStyle):
          """
          Sets the :class:`CubeColourDialog` window style flags.
  
          :param `agwStyle`: can only be ``CCD_SHOW_ALPHA`` or ``None``.
          """
  
          show = self.GetAGWWindowStyleFlag() & CCD_SHOW_ALPHA
          self._agwStyle = agwStyle
          
          self.mainSizer.Show(self.alphaSizers[0], show)
          self.mainSizer.Show(self.alphaSizers[1], show)
  
          self.mainSizer.Fit(self.mainPanel)
          self.mainSizer.SetSizeHints(self.mainPanel)
          self.mainSizer.Layout()            
          self.dialogSizer.Fit(self)
          self.dialogSizer.SetSizeHints(self)
          self.Layout()
  
          self.Refresh()
          self.Update()
          
  
      def GetAGWWindowStyleFlag(self):
          """
          Returns the :class:`CubeColourDialog` window style flags.
  
          :see: :meth:`~CubeColourDialog.SetAGWWindowStyleFlag` for a list of possible flags.        
          """
  
          return self._agwStyle        
          
              
      def OnOk(self, event):
          """
          Handles the Ok ``wx.EVT_BUTTON`` event for :class:`CubeColourDialog`.
  
          :param `event`: a :class:`CommandEvent` event to be processed.
          """
  
          self.EndModal(wx.ID_OK)
  
  
      def OnCancel(self, event):
          """
          Handles the Cancel ``wx.EVT_BUTTON`` event for :class:`CubeColourDialog`.
  
          :param `event`: a :class:`CommandEvent` event to be processed.
          """
  
          self.OnCloseWindow(event)
  
  
      def OnAddCustom(self, event):
          """
          Handles the Add Custom ``wx.EVT_BUTTON`` event for :class:`CubeColourDialog`.
  
          :param `event`: a :class:`CommandEvent` event to be processed.
          """
  
  
          self.customColours.AddCustom(self._colour)
  
    
      def OnShowAlpha(self, event):
          """
          Shows/hides the alpha channel control in :class:`CubeColourDialog`.
  
          :param `event`: a :class:`CommandEvent` event to be processed.
          """
  
          agwStyle = self.GetAGWWindowStyleFlag()
          show = event.IsChecked()
  
          if show:
              agwStyle |= CCD_SHOW_ALPHA
          else:
              agwStyle &= ~CCD_SHOW_ALPHA
  
          self.SetAGWWindowStyleFlag(agwStyle)
          
  
      def OnSpinCtrl(self, event):
          """
          Handles the ``wx.EVT_SPINCTRL`` event for RGB and HSB colours.
  
          :param `event`: a :class:`SpinEvent` event to be processed.
          """
  
          obj = event.GetEventObject()
          position = self.spinCtrls.index(obj)
          colourVal = event.GetInt()
  
          attribute, maxVal = colourAttributes[position], colourMaxValues[position]
  
          self.AssignColourValue(attribute, colourVal, maxVal, position)
  
  
      def OnAlphaSpin(self, event):
          """
          Handles the ``wx.EVT_SPINCTRL`` event for the alpha channel.
  
          :param `event`: a :class:`SpinEvent` event to be processed.
          """
  
          colourVal = event.GetInt()
          originalVal = self._colour._alpha
          if colourVal != originalVal and self._initOver:
              if colourVal < 0:
                  colourVal = 0
              if colourVal > 255:
                  colourVal = 255
  
              self._colour._alpha = colourVal
              self.DrawAlpha()
              
  
      def AssignColourValue(self, attribute, colourVal, maxVal, position):
          """ Common code to handle spin control changes. """
  
          originalVal = getattr(self._colour, attribute)
          if colourVal != originalVal and self._initOver:
              
              if colourVal < 0:
                  colourVal = 0
              if colourVal > maxVal:
                  colourVal = maxVal
  
              setattr(self._colour, attribute, colourVal)
              if position < 3:
                  self._colour.ToHSV()
              else:
                  self._colour.ToRGB()
  
              self.DrawAll()
              
  
      def DrawAll(self):
          """ Draws all the custom controls after a colour change. """
  
          if self._initOver and not self._inDrawAll:
              self._inDrawAll = True
  
              dc1 = wx.ClientDC(self.hsvBitmap)
              self.hsvBitmap.DrawMarkers(dc1)
              
              dc2 = wx.ClientDC(self.rgbBitmap)
              self.rgbBitmap.DrawMarkers(dc2)
              self.rgbBitmap.DrawLines(dc2)
  
              dc3 = wx.ClientDC(self.brightCtrl)
              self.brightCtrl.DrawMarkers(dc3)
  
              dc4 = wx.ClientDC(self.alphaCtrl)
              self.alphaCtrl.DrawMarkers(dc4)
              
              self.CalcCuboid()
              self.CalcRects()
  
              self.DrawRGB()
              self.DrawHSB()
              self.DrawBright()
              self.DrawAlpha()
              
              self.SetSpinVals()
              self._inDrawAll = False
  
  
      def GetColourData(self):
          """ Returns a wxPython compatible :class:`ColourData`. """
  
          self._colourData.SetColour(self._colour.GetPyColour())
          return self._colourData
  
  
      def GetRGBAColour(self):
          """ Returns a 4-elements tuple of red, green, blue, alpha components. """
  
          return (self._colour.r, self._colour.g, self._colour.b, self._colour._alpha)
  
      
      def GetHSVAColour(self):
          """ Returns a 4-elements tuple of hue, saturation, brightness, alpha components. """
  
          return (self._colour.h, self._colour.s, self._colour.v, self._colour._alpha)
  
  
  