1 module net.masterthought.rainbow.r;
2 
3 import std.array;
4 import std.conv;
5 import std.stdio;
6 import std.string;
7 import std.range;
8 import std.algorithm;
9 
10 R rainbow(string s){
11   return R.bow(s);
12 }
13 
14 enum Effect{
15 	bold = "1",
16 	dim = "2",
17 	underlined = "4",
18 	blink = "5",
19 	inverted = "7",
20 	hidden = "8"
21 }
22 
23 private static genColorEnums(string colorType){
24 	string[] colorList;
25 	colorList ~= "enum " ~ colorType ~ "{";
26 	if(colorType == "FgColor"){
27 		colorList ~= "original = \"39\",
28 	black = \"30\",
29 	red = \"31\",
30 	green = \"32\",
31 	yellow = \"33\",
32 	blue = \"34\",
33 	magenta = \"35\",
34 	cyan = \"36\",
35 	lightGray = \"37\",
36 	darkGray = \"90\",
37 	lightRed = \"91\",
38 	lightGreen = \"92\",
39 	lightYellow = \"93\",
40 	lightBlue = \"94\",
41 	lightMagenta = \"95\",
42 	lightCyan = \"96\",
43 	white = \"97\",";
44 	foreach(color ; iota(0,257)){
45       colorList ~= "c" ~ to!string(color) ~ " = " ~ "\"38;5;" ~ to!string(color) ~ "\",";
46 	}
47 	} else {
48 		colorList ~= "original = \"49\",
49 	black = \"40\",
50 	red = \"41\",
51 	green = \"42\",
52 	yellow = \"43\",
53 	blue = \"44\",
54 	magenta = \"45\",
55 	cyan = \"46\",
56 	lightGray = \"47\",
57 	darkGray = \"100\",
58 	lightRed = \"101\",
59 	lightGreen = \"102\",
60 	lightYellow = \"103\",
61 	lightBlue = \"104\",
62 	lightMagenta = \"105\",
63 	lightCyan = \"106\",
64 	white = \"107\",";
65 	foreach(color ; iota(0,257)){
66       colorList ~= "c" ~ to!string(color) ~ " = " ~ "\"48;5;" ~ to!string(color) ~ "\",";
67 	}
68 	}
69 	colorList ~= "}";
70 	return colorList.join("");
71 }
72 
73 mixin(genColorEnums("FgColor"));
74 mixin(genColorEnums("BgColor"));
75 
76 class R{
77 
78 private string content;
79 private string[] codes = ["\033["];
80 
81 this(string content){
82   this.content = content;
83 }
84 
85 // makes .red and .onRed etc...
86 private static genColors(string colorType){
87      string[] colorList;
88 	 foreach(color ; [__traits(allMembers, FgColor)]){
89 	  string methName = colorType == "FgColor" ? color : "on" ~ to!string(color[0]).capitalize() ~ to!string(color[1..$]);
90       colorList ~= "@property public R " ~ methName ~ "(){ codes ~= " ~ colorType ~ "." ~ color ~ " ; codes ~= \";\" ; return this;}";
91     }
92     return colorList.join("");
93 }
94 
95 // makes .blink effects etc
96 private static genEffects(){
97      string[] effectList;
98 	 foreach(effect ; [__traits(allMembers, Effect)]){
99       effectList ~= "@property public R " ~ effect ~ "(){ codes ~= Effect." ~ effect ~ " ; codes ~= \";\" ; return this;}";
100     }
101     return effectList.join("");
102 }
103 
104 mixin(genColors("FgColor"));
105 mixin(genColors("BgColor"));
106 mixin(genEffects());
107 
108 public static R bow(string content){
109 	return new R(content);
110 }
111 
112  public R fg(FgColor color){
113    codes ~= color;
114    codes ~= ";";
115    return this;
116  }
117 
118   public R bg(BgColor color){
119   codes ~= color;
120   codes ~= ";";
121    return this;
122  }
123 
124   public R ef(Effect effect){
125   codes ~= effect;
126   codes ~= ";";
127    return this;
128  }
129 
130   override public string toString(){
131   	if(codes[$-1] == ";"){
132   		codes.popBack;
133   	}
134  	codes ~= "m" ~ content ~ "\033[0m";
135  	//writeln(codes);
136     return codes.join("");
137  }
138 
139  string opBinary(string op)(R rhs)
140 {
141     static if (op == "~"){
142      return this.toString() ~ rhs.toString();
143     }
144     else static assert(0, "Operator "~op~" not implemented");
145 }
146 
147  string opBinaryRight(string op)(string lhs)
148 {
149     static if (op == "~"){
150      return lhs ~ this.toString();
151     }
152     else static assert(0, "Operator "~op~" not implemented");
153 }
154 
155 public void logo(){
156   writeln("");
157   writeln(R.bow("╦═╗").red.onBlack, R.bow("╔═╗").c208.onBlack, R.bow("╦").c221.onBlack, R.bow("╔╗╔").green.onBlack, R.bow("╔╗").cyan.onBlack, R.bow(" ╔═╗").c57.onBlack, R.bow("╦ ╦").c99.onBlack);
158   writeln(R.bow("╠╦╝").red.onBlack,R.bow("╠═╣").c208.onBlack, R.bow("║").c221.onBlack, R.bow("║║║").green.onBlack, R.bow("╠╩╗").cyan.onBlack, R.bow("║ ║").c57.onBlack, R.bow("║║║").c99.onBlack);
159   writeln(R.bow("╩╚═").red.onBlack,R.bow("╩ ╩").c208.onBlack, R.bow("╩").c221.onBlack, R.bow("╝╚╝").green.onBlack, R.bow("╚═╝").cyan.onBlack, R.bow("╚═╝").c57.onBlack,R.bow("╚╩╝").c99.onBlack);
160   writeln("");
161 }
162 
163 }
164