

// MARK: - hue contants

var themeHue = 195
var blockLiveHue = 42
var lightLiveHue = 35
var darkLiveHue = 40


// MARK: - general color funcs

function colorHSBA(hue, saturation, brightness, alpha)
{
	return {
		"+": "BaseColor",
		gxHue: hue,
		gxSaturation: saturation,
		gxBrightness: brightness,
		gxAlpha: alpha,
	};
}

function colorMono(brightness, alpha)
{
	return {
		"+": "BaseColor",
		gxHue: 0,	// red, but it has to be some color ;)
		gxSaturation: 0,
		gxBrightness: brightness,
		gxAlpha: alpha,
	};
}

//  change alpha in a color dictionary
Object.defineProperty( Object.prototype, "withAlpha",
{ enumerable: false,
  value: function(alpha)
          {
              var result = Object.create(this);
              result.gxAlpha = alpha;
              return result;
          }
});


// MARK: - special color funcs

function errorColor(brightness, saturation)
{
	var saturation = saturation || 74;

	return {
		"+": "BaseColor",
		gxHue: 7,
		gxBrightness: brightness,
		gxSaturation: saturation,
		gxAlpha: 100,
		blockDisabled: {
            gxDesaturate: 20,
            gxFadeTo: { gxFadePercent: 5, gxBrightness: 40 }
		},
	};
}

function warningForeColorFunc(lightBrightness, darkBrightness)
{
	return {
		"+": "BaseColor",
		gxHue: 48,
		gxBrightness: darkBrightness,
		gxSaturation: saturation,
		gxAlpha: 100,
        lightMode:
        {
            gxBrightness: lightBrightness,
        },
	};
}


// MARK: - light/dark color funcs

function mainColorFunc(lightBrightness, darkBrightness)
{
    return {
        "+": "BaseColor",
        gxHue: 0,
        gxAlpha: 100,
        gxSaturation: 0,
        gxBrightness: darkBrightness,
		withLive: {
			live: {	gxHue: darkLiveHue,
					gxBrightness: 100,
					gxSaturation: 100, },
			lightMode:
			{
				gxBrightness: lightBrightness,
				live: {	gxHue: lightLiveHue,
						gxBrightness: 100,
						gxSaturation: 100, },
			},
		},
        lightMode:
        {
            gxBrightness: lightBrightness,
        },
    };
}

function themeColorFunc(lightBrightness, darkBrightness)
{
    return {
        "+": "BaseColor",
        gxHue: themeHue,
        gxAlpha: 100,
        gxSaturation: 90,
        gxBrightness: darkBrightness,
        lightMode:
        {
            //gxSaturation: 74,
            gxBrightness: lightBrightness,
        },
    };
}

function themePaleColorFunc(lightBrightness, darkBrightness)
{
	return {
		"+": "BaseColor",
		gxHue: themeHue,
		gxAlpha: 100,
		gxSaturation: 39,
		gxBrightness: darkBrightness,
		lightMode:
		{
			//gxSaturation: 74,
			gxBrightness: lightBrightness,
		},
	}
}

function themeForeColorFunc(lightBrightness, darkBrightness)
{
    return {
        "+": "BaseColor",
        gxHue: themeHue,
        gxAlpha: 100,
        gxSaturation: (100 - darkBrightness) * 4,
        gxBrightness: darkBrightness,
        lightMode:
        {
            gxSaturation: (100 - lightBrightness) * 4,
            gxBrightness: lightBrightness,
        },
    };
}

function themeColorCombineFunc(lightColor, darkColor)
{
    return {
        "+": "BaseColor",
        gxHue: darkColor.gxHue,
        gxAlpha: darkColor.gxAlpha,
        gxSaturation: darkColor.gxSaturation,
        gxBrightness: darkColor.gxBrightness,
        lightMode: lightColor,
    };
}

function selectionColorFunc(lightBrightness, darkBrightness)
{
	return {
		"+": "BaseColor",
		gxHue: themeHue,
		gxAlpha: 100,
		gxSaturation: 39,
		gxBrightness: darkBrightness,
		lightMode:
		{
			//gxSaturation: 100 - lightBrightness / 2,
			gxBrightness: lightBrightness,
		},
	};
}

function listSelectionColorFunc(lightBrightness, darkBrightness)
{
    lightBrightness = lightBrightness || 95;
    darkBrightness = darkBrightness || 37;

	return {
		"+": "BaseColor",
		gxHue: themeHue,
		gxAlpha: 100,
		gxSaturation: 76,
		gxBrightness: darkBrightness,
		lightMode:
		{
			gxSaturation: 25,
			gxBrightness: lightBrightness,
		},
	};
}

function foreThemeLiveColorFunc(saturation)
{
    return {
        "+": "BaseColor",
        gxHue: themeHue,
        gxAlpha: 100,
		gxSaturation: saturation,
        gxBrightness: 100,
        live: {
			gxHue: blockLiveHue,	// for use on blue block face
            gxSaturation: 60,
        },
        lightMode:
        {
            live: {
				gxHue: blockLiveHue,	// for use on blue block face
                gxSaturation: 60,
            },
        },
    };
}

function themeLiveColorFunc(lightBrightness, darkBrightness)
{
    return {
        "+": "BaseColor",
        gxHue: themeHue,
        gxAlpha: 100,
        gxSaturation: 90,
        gxBrightness: darkBrightness,
        live: {
            gxHue: darkLiveHue,
            gxBrightness: 100,
            gxSaturation: 100,
        },
        lightMode:
        {
            gxBrightness: lightBrightness,
            live: {
                gxHue: lightLiveHue,
                gxBrightness: 100,
                gxSaturation: 100,
            },
        },
    };
}

function liveColorFunc(lightBrightness, darkBrightness)	// always orange
{
    return {
        "+": "BaseColor",
        gxHue: darkLiveHue,
        gxAlpha: 100,
        gxSaturation: 100,
        gxBrightness: 100,
        lightMode:
        {
			gxHue: lightLiveHue,
        },
		blockFace:
		{
			lightMode: {},
			gxHue: blockLiveHue,
		},
    };
}

function statusLightColorFunc()    // green and dark green
{
    return {
        "+": "BaseColor",
        gxHue: 105,
        gxAlpha: 100,
        gxSaturation: 100,
        gxBrightness: 100,
        disabled:
        {
            gxBrightness: 32,
        },
    };
}

function trialColor(step)
{
    return {
        "+": "BaseColor",
        gxAlpha: 100,
        gxHue: darkLiveHue / 10.0 * (10.0 - step),
        gxBrightness: 95,
        gxSaturation: 90 + step,
        lightMode:
        {
            gxBrightness: 95,
            gxSaturation: 90 + step,
        },
    };
}


Object.defineProperty( Object.prototype, "darken",
	{ enumerable: false,
	  value: function(percentDarker)	// expect 0 to 100, negative will lighten
			  {
				  var result = Object.create(this);

				  var factor = percentDarker/100.0
				  result.gxBrightness *= 1.0 - factor;
				  result.gxSaturation *= 1.0 + factor/5.0;

				  return result;
			  }
	});

Object.defineProperty( Object.prototype, "withSaturation",
	{ enumerable: false,
	  value: function(saturation)	// expect 0 to 100
			  {
				  var result = Object.create(this);
				  result.gxSaturation = saturation;
				  return result;
			  }
	});

Object.defineProperty( Object.prototype, "withPressed",
	{ enumerable: false,
	  value: function(pressedValue)
			  {
				  var result = Object.create(this);
				  result.gxPressedEffect = pressedValue || 10;
				  return result;
			  }
	});



markup.push({

    // MARK: - base color

    BaseColor:
	{
        nsClass: "NSColor",
        noPressed: {
			pressed: {}, // swap pressed for nothing
        },
        pressed: {
            gxPressedEffect: 15,
        },
        disabled: {
            gxAlpha: 50,
            pressed: {
                gxPressedEffect: 0,
            },
        },
		noLightMode: {
			lightMode: {}
		},
		withHover: {
			hover: {
				gxPressedEffect: 8,
			},
		},
		withOn: {
			on: {
				gxBrightness: 0,
			},
		},
		noDisabled: {
			disabled: {}
		},
		dimmed: {
			gxAlpha: 70,
		},
        alphaBg: {
            gxAlpha: 10,
        },
        blockDisabled:  {
            gxDesaturate: 70,
            gxFadeTo: { gxFadePercent: 30, gxBrightness: 40 }
        },
        noBlockDisabled: {
            blockDisabled: {}, // swap blockDisabled for nothing
        },
		desaturate: {
			gxDesaturate: 90,
		},
    },

	// for uncolored labels etc
    ForeColor1: mainColorFunc(20, 100), // control titles etc
    ForeColor2: mainColorFunc(52, 72),  // labels etc
	ForeColor3: mainColorFunc(62, 62),  // labels etc

    // for uncolored backgrounds etc
    BackColor1: mainColorFunc(100, 18.5),  // main graph back etc
    BackColor2: mainColorFunc(85, 13.3),  // groups etc
    BackColor3: mainColorFunc(91, 24),   // controls, features etc
    BackColor4: mainColorFunc(67, 27),   // switch 'off' color
	
	BlackOrWhite: mainColorFunc(100, 0),  // black for dark mode/white for light

	// 'sidebar' is now a lie, used for more than that
    SidebarBackColor1: mainColorFunc(94, 18.5),
    SidebarBackColor2: mainColorFunc(100, 13.3),
	SidebarBackColor3: mainColorFunc(94, 13.3),

	ListBackColor3: mainColorFunc(89, 24),   // controls, features etc - in list items

    LCDForeColor1: mainColorFunc(100, 100),
    LCDBackColor2: mainColorFunc(18.5, 13.3),
    
	// theme blue background colors (sometimes not used for background).
 	ColorTheme1: themeColorFunc(87, 87),
 	ColorTheme2: themeColorFunc(69, 69),
 	ColorTheme3: themeColorFunc(46, 46),
	
	ColorThemePale: themePaleColorFunc(80, 100),

	// very lightly tinted (or white) colors for use on theme blue backgrounds
    ForeColorTheme1: themeForeColorFunc(100, 100), // control titles etc
    ForeColorTheme2: themeForeColorFunc(95, 95),

    // theme blue that turns 'orange' when live
    ColorThemeLive1: themeLiveColorFunc(87, 87),
    ColorThemeLive2: themeLiveColorFunc(98, 98),
    ColorThemeLive3: foreThemeLiveColorFunc(39),	// saturation 39 for light blue. then live orange

    ColorLive1: liveColorFunc(87, 87),	// always orange
	
    TextSelectionColor: listSelectionColorFunc(90, 55), //themeColorFunc(82, 77),     // text selection etc
    
	SelectionColor2: selectionColorFunc(100, 100),  // block selection etc
	SelectionColor3: listSelectionColorFunc(), // colorHSBA(themeHue, 76, 37, 100),  // list selection
	SelectionColor4: selectionColorFunc(100, 100),  // wire selection

    RecordingColor: colorHSBA(3, 71, 94, 100),
    
    StatusLightColor: statusLightColorFunc(),
    
	ErrorColor: errorColor(91),
    
	WarningForeColor: themeColorCombineFunc(colorMono(0, 100), colorHSBA(48, 100, 100, 100)),
	WarningBackColor: themeColorCombineFunc(colorHSBA(48, 12, 100, 100), colorHSBA(48, 43, 28, 100)),
	
    NoticeFillColor: themeColorCombineFunc(colorHSBA(48, 22, 100, 100), colorHSBA(47, 56, 32, 100)),
    WhiteOrBlack: mainColorFunc(0, 1000),
    
    DropHiliteColor: selectionColorFunc(100, 100),
    
    NoColor: colorHSBA(0, 0, 0, 0),
	RedColor: colorHSBA(0, 100, 100, 100),
	BlackColor: colorMono(0, 100),
	Gray50Color: colorMono(50, 100),
    WhiteColor: colorMono(100, 100),

	SyntaxNoneColor: mainColorFunc(20, 95),
	SyntaxCommentColor: mainColorFunc(45, 72),
	SyntaxQuoteColor: liveColorFunc(40, 87),
	SyntaxIdentifierColor: themeColorFunc(87, 92),
	SyntaxFunctionColor: themeColorFunc(90, 95),
	SyntaxNumberColor: colorHSBA(142, 89, 82, 100),
	SyntaxRequiresColor: colorHSBA(281, 74, 98, 100),
	SyntaxErrorColor: colorHSBA(7, 74, 98, 100),

    TrialFillPainter:
    {
		nsClass: "GXPainter",
		gxFillColor: "BlackColor",
  
		"0": { gxFillColor: "ColorTheme1",
			animating: { gxFillColor: trialColor(0) },
		},
		"1": { gxFillColor: trialColor(0) },
		"2": { gxFillColor: trialColor(1) },
		"3": { gxFillColor: trialColor(2) },
		"4": { gxFillColor: trialColor(3) },
		"5": { gxFillColor: trialColor(4) },
		"6": { gxFillColor: trialColor(5) },
		"7": { gxFillColor: trialColor(6) },
		"8": { gxFillColor: trialColor(7) },
		"9": { gxFillColor: trialColor(8) },
		"10": { gxFillColor: trialColor(10) },
    },
})
