View difference between Paste ID: QdjNhAaN and BTapaijn
SHOW: | | - or go back to the newest paste.
1
// ==PREPROCESSOR==
2
// @name "Youtube Radio"
3
// @author "Mire777"
4
// @feature "v1.4"
5
// @feature "watch-metadb"
6
// ==/PREPROCESSOR==
7
8
// Paths
9
var fbfolder = (fb.ProfilePath + "Artist_info");
10
var lfm_folder = fbfolder;
11
12
//image download size
13
size = "high";
14
15
//Download server
16
auto_yt = window.GetProperty("YT Radio", "0");
17
//auto_lfm = window.GetProperty("LFM Radio", "0");
18
19
ooo2 = window.GetProperty("YT Track", "");
20
START_ARTIST = window.GetProperty("Artist Station", "");
21
22
//Download server
23
last_fm = window.GetProperty("YT Similar", "");
24
YT_URL = window.GetProperty("YT URL", "");
25
26
27
//Search terms(google,yahoo)
28
terms = "";
29
30
//Cycle
31
cycle2 = 15;
32
33
var VERSION = "7.2013-10-19.01";
34
var DT_LEFT = 0x00000000;
35
var DT_CENTER = 0x00000001;
36
var DT_RIGHT = 0x00000002;
37
var DT_VCENTER = 0x00000004;
38
var DT_WORDBREAK = 0x00000010;
39
var DT_CALCRECT = 0x00000400;
40
var DT_NOPREFIX = 0x00000800;
41
var DT_END_ELLIPSIS = 0x00008000;
42
43
var MF_GRAYED = 0x00000001;
44
var MF_STRING = 0x00000000;
45
46
var IDC_ARROW = 32512;
47
var IDC_HAND = 32649;
48
49
var ONE_DAY = 86400000;
50
var ONE_WEEK = 604800000;
51
52
String.prototype.addCommas = function() {
53
	return this.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
54
}
55
56
String.prototype.trim = function() {
57
	return this.replace(/^\s+|\s+$/g, "");
58
}
59
60
String.prototype.ucfirst = function() {
61
	return this.charAt(0).toUpperCase() + this.substr(1);
62
}
63
64
function RGB(r, g, b) {
65
	return (0xff000000 | (r << 16) | (g << 8) | (b));
66
}
67
68
function RGBA(r, g, b, a) {
69
	return ((a << 24) | (r << 16) | (g << 8) | (b));
70
}
71
72
function on_colors_changed() {
73
	p.colors_changed();
74
}
75
76
function on_font_changed() {
77
	p.font_changed();
78
}
79
80
function on_selection_changed() {
81
	p.item_focus_change();
82
}
83
84
function on_playlist_switch() {
85
	p.item_focus_change();
86
}
87
88
function on_playback_new_track() {
89
	p.item_focus_change();
90
    //im.download();
91
    im.downloadLFM();
92
}
93
94
function on_playback_dynamic_info_track() {
95
	p.item_focus_change();
96
}
97
98
function on_playback_stop() {
99
	p.item_focus_change();
100
}
101
102
function on_item_focus_change() {
103
	p.item_focus_change();
104
}
105
106
function on_mouse_leave() {
107
	if (typeof b == "object") b.leave();
108
	if (typeof r == "object") r.leave();
109
	if (typeof li == "object") li.leave();
110
	if (typeof s == "object") s.leave();
111
}
112
113
function on_mouse_rbtn_up(x, y) {
114
	p.rbtn_up(x, y);
115
	return true;
116
}
117
118
function on_notify_data(name, data) {
119
	if (name == "lastfm" && data == "update" && typeof l == "object") l.notify_data(name, data);
120
	if (name == "autoplaylists" && data == "update" && typeof li == "object" && li.mode == "autoplaylists") li.update();
121
	if (name == "images" && data == "update" && typeof im == "object") im.update();
122
	if (name == "love" && typeof ps == "object") l.post(fb.TitleFormat("%LASTFM_LOVED_DB%").EvalWithMetadb(data) == 1 ? "track.unlove" : "track.love", data);
123
}
124
125
function panel(name, features) {
126
	this.item_focus_change = function() {
127
		if (!this.metadb_func) return;
128
		switch(this.selection_mode) {
129
			case 0:
130
				this.metadb = fb.GetSelection();
131
				break;
132
			case 1:
133
				this.metadb = fb.IsPlaying ? fb.GetNowPlaying() : fb.GetFocusItem();
134
				break;
135
			case 2:
136
				this.metadb = fb.GetFocusItem();
137
				break;
138
		}
139
		if (this.metadb) on_metadb_changed();
140
	}
141
	
142
this.colors_changed = function() {
143
		if (this.dui) {
144
            this.background_mode=(1);
145
			this.textcolour = window.GetColorDUI(0);
146
			this.textcolour_hl = window.GetColorDUI(2);
147
			this.backcolour = window.GetColorDUI(1);
148
		} else {
149
            this.background_mode=(0);
150
			this.textcolour = window.GetColorCUI(0);
151
			this.textcolour_hl = window.GetColorCUI(0);
152
			this.backcolour = window.GetColorCUI(3);
153
		}
154
		window.Repaint();
155
	}
156
	
157
	this.font_changed = function() {
158
		this.font = this.dui ? window.GetFontDUI(0) : window.GetFontCUI(0);
159
		try {
160
			this.font_name = this.font.Name;
161
		} catch(e) {
162
			this.console("Unable to use your default font. Using Segoe UI instead.");
163
			this.font_name = "Segoe ui";
164
		}
165
		this.title_font = gdi.Font(this.font_name, 16, 1);
166
		this.normal_font = gdi.Font("segoe ui", 12, 1);
167
		this.fixed_font = gdi.Font("Lucida Console", this.normal_font_size);
168
		this.list_font = gdi.Font(this.font_name, this.list_font_size);
169
		this.row_height = this.normal_font.Height + 2;
170
		if (typeof t == "object") t.size();
171
		window.Repaint();
172
	}
173
	
174
	this.size = function() {
175
		this.w = window.Width;
176
		this.h = window.Height;
177
	}
178
	
179
	this.move = function(x, y) {
180
		this.mx = x;
181
		this.my = y;
182
	}
183
	
184
	this.rbtn_up = function(x, y) {
185
		var _menu = window.CreatePopupMenu();
186
		var _custom_background = window.CreatePopupMenu();
187
		var _metadb = window.CreatePopupMenu();
188
		var _cover = window.CreatePopupMenu();
189
		var _font = window.CreatePopupMenu();
190
		var _sub1 = window.CreatePopupMenu();
191
		var _sub2 = window.CreatePopupMenu();
192
		var _sub3 = window.CreatePopupMenu();
193
		var _sub4 = window.CreatePopupMenu();
194
		var _sub5 = window.CreatePopupMenu();
195
		var idx;
196
		switch(true) {
197
			case typeof a == "object" && a.trace(x, y):
198
				/*_menu.AppendMenuItem(MF_STRING, 1, "Refresh");
199
				_menu.AppendMenuSeparator();
200
				_menu.AppendMenuItem(MF_STRING, 2, "Front");
201
				_menu.AppendMenuItem(MF_STRING, 3, "Back");
202
				_menu.AppendMenuItem(MF_STRING, 4, "Disc");
203
				_menu.AppendMenuItem(MF_STRING, 5, "Icon");
204
				_menu.AppendMenuItem(MF_STRING, 6, "Artist");
205
				_menu.CheckMenuRadioItem(2, 6, a.id + 2);
206
				_menu.AppendMenuSeparator();*/
207
				_menu.AppendMenuItem(MF_STRING, 15, "Crop (focus on centre)");
208
				_menu.AppendMenuItem(MF_STRING, 16, "Crop (focus on top)");
209
				_menu.AppendMenuItem(MF_STRING, 17, "adjust");
210
				_menu.AppendMenuItem(MF_STRING, 18, "Stretch");
211
				_menu.CheckMenuRadioItem(15, 18, a.type == "centre" ? 15 : a.type == "top" ? 16 : a.type == "adjust" ? 17 : 18);
212
				_menu.AppendMenuSeparator();
213
				_cover.AppendMenuItem(this.metadb ? MF_STRING : MF_GRAYED, 21, "Google images (launches browser)");
214
				_cover.AppendMenuItem(this.metadb ? MF_STRING : MF_GRAYED, 22, "Album Art Downloader");
215
				_cover.AppendMenuSeparator();
216
				//_cover.AppendMenuItem(MF_STRING, 23, "Help");
217
				//_cover.AppendTo(_menu, MF_STRING, "Cover search");
218
				//_menu.AppendMenuSeparator();
219
				break;
220
			case typeof c == "object" && c.trace(x, y):
221
				if (this.check_feature("now_playing") && !np_cd) break;
222
				/*_menu.AppendMenuItem(MF_STRING, 1, "Refresh");
223
				_menu.AppendMenuSeparator();
224
				_menu.AppendMenuItem(MF_STRING, 11, "Gloss effect");
225
				_menu.CheckMenuItem(11, c.gloss);
226
				_menu.AppendMenuItem(MF_STRING, 12, "Shadow effect");
227
				_menu.CheckMenuItem(12, c.shadow);
228
				_menu.AppendMenuSeparator();
229
				_cover.AppendMenuItem(this.metadb ? MF_STRING : MF_GRAYED, 21, "Google images (launches browser)");
230
				_cover.AppendMenuItem(this.metadb ? MF_STRING : MF_GRAYED, 22, "Album Art Downloader");
231
				_cover.AppendMenuSeparator();
232
				_cover.AppendMenuItem(MF_STRING, 23, "Help");
233
				_cover.AppendTo(_menu, MF_STRING, "Cover search");
234
				_menu.AppendMenuSeparator();*/
235
				break;
236
			case typeof li == "object" && li.trace(x, y):
237
				switch(li.mode) {
238
					case "autoplaylists":
239
						_menu.AppendMenuItem(MF_STRING, 600, "Change title...");
240
						_menu.AppendMenuSeparator();
241
						for (i = 1; i < 9; i++) {
242
							_sub1.AppendMenuItem(MF_STRING, i + 600, i);
243
						}
244
						_sub1.AppendTo(_menu, MF_STRING, "Save slot");
245
						_sub1.CheckMenuRadioItem(601, 608, li.autoplaylists_slot + 600);
246
						_menu.AppendMenuSeparator();
247
						_sub2.AppendMenuItem(MF_STRING, 610, "run query");
248
						_sub2.AppendMenuItem(MF_STRING, 611, "do nothing");
249
						_sub2.CheckMenuRadioItem(610, 611, li.autoplaylists_success ? 610 : 611);
250
						_sub2.AppendTo(_menu, MF_STRING, "On successful creation/edit");
251
						for (i = 0; i < li.autoplaylists_deleted_items.length; i++) {
252
							var temp = li.autoplaylists_deleted_items[i].split("¬");
253
							_sub3.AppendMenuItem(MF_STRING, i + 620, temp[0]);
254
						}
255
						if (li.autoplaylists_deleted_items.length > 0) _sub3.AppendTo(_menu, MF_STRING, "Restore");
256
						_menu.AppendMenuSeparator();
257
						_menu.AppendMenuItem(MF_STRING, 650, "Replace exisiting playlists with the same name");
258
						_menu.CheckMenuItem(650, li.autoplaylists_remove_duplicates);
259
						_menu.AppendMenuSeparator();
260
						break;
261
					case "discogs":
262
						_menu.AppendMenuItem(MF_STRING, 29, "Show exact artist matches only");
263
						_menu.CheckMenuItem(29, li.discogs_match);
264
						_menu.AppendMenuSeparator();
265
						_menu.AppendMenuItem(MF_STRING, 28, "Show timestamp");
266
						_menu.CheckMenuItem(28, li.show_timestamp);
267
						_menu.AppendMenuSeparator();
268
						break;
269
					case "echonest":
270
						for (i = 0; i < li.echonest_modes.length; i++) {
271
							_menu.AppendMenuItem(MF_STRING, i + 500, li.echonest_modes[i].ucfirst());
272
						}
273
						_menu.CheckMenuRadioItem(500, 502, li.echonest_mode + 500);
274
						_menu.AppendMenuSeparator();
275
						_menu.AppendMenuItem(MF_STRING, 28, "Show timestamp");
276
						_menu.CheckMenuItem(28, li.show_timestamp);
277
						_menu.AppendMenuSeparator();
278
						break;
279
					case "lastfm":
280
						for (i = 0; i < li.lastfm_modes.length; i++) {
281
							_menu.AppendMenuItem(MF_STRING, 801 + i, li.lastfm_modes[i].ucfirst());
282
						}
283
						_menu.CheckMenuRadioItem(801, 805, li.lastfm_mode + 801);
284
						_menu.AppendMenuSeparator();
285
						if (li.lastfm_mode == 0) {
286
							if (li.lastfm_button == "spotify") {
287
								_menu.AppendMenuItem(MF_STRING, 810, "Pause playback when launching Spotify");
288
								_menu.CheckMenuItem(810, li.lastfm_pause);
289
								_menu.AppendMenuSeparator();
290
							}
291
							/*_sub1.AppendMenuItem(MF_STRING, 811, "Spotify");
292
							_sub1.AppendMenuItem(MF_STRING, 812, "Autoplaylist");
293
							_sub1.CheckMenuRadioItem(811, 812, li.lastfm_button == "spotify" ? 811 : 812);
294
							_sub1.AppendTo(_menu, MF_STRING, "Buttons");
295
							_menu.AppendMenuSeparator();*/
296
						}
297
						/*_menu.AppendMenuItem(MF_STRING, 28, "Show timestamp");
298
						_menu.CheckMenuItem(28, li.show_timestamp);
299
						_menu.AppendMenuSeparator();
300
						_menu.AppendMenuItem(MF_STRING, 51, "Last.fm auto-correct");
301
						_menu.CheckMenuItem(51, l.auto_correct);
302
						_menu.AppendMenuSeparator();*/
303
						break;
304
					case "lastfm_charts":
305
						_menu.AppendMenuItem(l.username.length > 0 ? MF_STRING : MF_GRAYED, 1000, "Refresh");
306
						_menu.AppendMenuSeparator();
307
						for (i = 0; i < li.lastfm_charts_modes.length; i++) {
308
							_menu.AppendMenuItem(MF_STRING, i + 1001, li.lastfm_charts_modes[i].ucfirst());
309
						}
310
						_menu.CheckMenuRadioItem(1001, 1003, li.lastfm_charts_mode + 1001);
311
						_menu.AppendMenuSeparator();
312
						for (i = 0; i < li.lastfm_charts_periods_display.length; i++) {
313
							_menu.AppendMenuItem(MF_STRING, i + 1004, li.lastfm_charts_periods_display[i].ucfirst());
314
						}
315
						/*_menu.CheckMenuRadioItem(1004, 1009, li.lastfm_charts_period + 1004);
316
						_menu.AppendMenuSeparator();
317
						_menu.AppendMenuItem(MF_STRING, 1010, "Bar colour...");
318
						_menu.AppendMenuSeparator();
319
						_menu.AppendMenuItem(MF_STRING, 28, "Show timestamp");
320
						_menu.CheckMenuItem(28, li.show_timestamp);
321
						_menu.AppendMenuSeparator();*/
322
						break;
323
					case "musicbrainz":
324
						_menu.AppendMenuItem(MF_STRING, 700, "Releases");
325
						_menu.AppendMenuItem(MF_STRING, 701, "Links");
326
						_menu.CheckMenuRadioItem(700, 701, li.musicbrainz_mode == "releases" ? 700 : 701);
327
						_menu.AppendMenuSeparator();
328
						if (li.musicbrainz_mode == "releases") {
329
							/*_menu.AppendMenuItem(MF_STRING, 702, "Include albums");
330
							_menu.CheckMenuItem(702, li.musicbrainz_album);
331
							_menu.AppendMenuItem(MF_STRING, 703, "Include EPs");
332
							_menu.CheckMenuItem(703, li.musicbrainz_ep);
333
							_menu.AppendMenuItem(MF_STRING, 704, "Include singles");
334
							_menu.CheckMenuItem(704, li.musicbrainz_single);
335
							_menu.AppendMenuSeparator();
336
							_menu.AppendMenuItem(MF_STRING, 705, "Include 'Live' releases");
337
							_menu.CheckMenuItem(705, li.musicbrainz_live);
338
							_menu.AppendMenuItem(MF_STRING, 706, "Include 'Remix' releases");
339
							_menu.CheckMenuItem(706, li.musicbrainz_remix);
340
							_menu.AppendMenuItem(MF_STRING, 707, "Include 'Compilation' releases");
341
							_menu.CheckMenuItem(707, li.musicbrainz_compilation);
342
							_menu.AppendMenuSeparator();
343
							_menu.AppendMenuItem(MF_STRING, 708, "Show release type");
344
							_menu.CheckMenuItem(708, li.musicbrainz_show_release_type);
345
							_menu.AppendMenuSeparator();*/
346
						}
347
						/*_menu.AppendMenuItem(MF_STRING, 28, "Show timestamp");
348
						_menu.CheckMenuItem(28, li.show_timestamp);
349
						_menu.AppendMenuSeparator();*/
350
						break;
351
				}
352
				break;
353
			case typeof ps == "object" && b.buttons.ps.trace(x, y):
354
				/*_sub1.AppendMenuItem(utils.CheckComponent("foo_customdb", true) && !ps.loved_working && !ps.playcount_working && l.username.length > 0 ? MF_STRING : MF_GRAYED, 1100, "loved tracks and playcount");
355
				_sub1.AppendMenuItem(utils.CheckComponent("foo_customdb", true) && !ps.loved_working && !ps.playcount_working && l.username.length > 0 ? MF_STRING : MF_GRAYED, 1109, "loved tracks only");
356
				_sub1.AppendMenuSeparator();
357
				_sub1.AppendMenuItem(utils.CheckComponent("foo_customdb", true) && this.fso.FileExists(ps.sql_file) ? MF_STRING : MF_GRAYED, 1101, "from file");
358
				_sub1.AppendMenuSeparator();
359
				_sub1.AppendMenuItem(MF_STRING, 1102, "Show console");
360
				_sub1.CheckMenuItem(1102, ps.show_console);
361
				_sub1.AppendTo(_menu, MF_STRING, "Library import");
362
				_menu.AppendMenuSeparator();
363
				_sub2.AppendMenuItem(MF_STRING, 1103, "Only update tracks in library");
364
				_sub2.CheckMenuItem(1103, ps.library);
365
				_sub2.AppendMenuItem(MF_STRING, 52, "Last.fm auto-correct");
366
				_sub2.CheckMenuItem(52, l.auto_correct);
367
				_sub2.AppendTo(_menu, MF_STRING, "Auto-updates");
368
				_menu.AppendMenuSeparator();
369
				_sub3.AppendMenuItem(MF_STRING, 1104, "Off");
370
				_sub3.AppendMenuItem(MF_STRING, 1105, "On");
371
				_sub3.CheckMenuRadioItem(1104, 1105, ps.auto_love ? 1105 : 1104);
372
				_sub3.AppendMenuSeparator();
373
				_sub3.AppendMenuItem(ps.auto_love ? MF_STRING : MF_GRAYED, 1106, "Condition");
374
				_sub3.AppendTo(_menu, MF_STRING, "Automatically love tracks");
375
				_menu.AppendMenuSeparator();
376
				_sub4.AppendMenuItem(MF_STRING, 1107, "tango");
377
				_sub4.AppendMenuItem(MF_STRING, 1108, "silk");
378
				_sub4.CheckMenuRadioItem(1107, 1108, ps.icon == "tango" ? 1107 : 1108);
379
				_sub4.AppendTo(_menu, MF_STRING, "Icon");
380
				_menu.AppendMenuSeparator();*/
381
				break;
382
			case typeof s == "object" && s.mode == "spectrogram" && s.trace(x, y) :
383
				/*_menu.AppendMenuItem(MF_STRING, 1804, "SoX options...");
384
				_menu.AppendMenuSeparator();
385
				_menu.AppendMenuItem(MF_STRING, 1805, "Marker colour...");
386
				_menu.AppendMenuSeparator();
387
				_menu.AppendMenuItem(MF_STRING, 1803, "Only analyse tracks in library");
388
				_menu.CheckMenuItem(1803, s.library);
389
				_menu.AppendMenuSeparator();
390
				_sub1.AppendMenuItem(MF_STRING, 1800, "Clear all");
391
				_sub1.AppendMenuItem(MF_STRING, 1801, "Clear older than 1 day");
392
				_sub1.AppendMenuItem(MF_STRING, 1802, "Clear older than 1 week");
393
				_sub1.AppendMenuSeparator();
394
				_sub1.AppendMenuItem(MF_GRAYED, 1803, "In use: " + (this.fso.GetFolder(spectrogram_cache).size / 1048576).toFixed(2) + "MB");
395
				_sub1.AppendTo(_menu, MF_STRING, "Cached images");
396
				_menu.AppendMenuSeparator();*/
397
				break;
398
			case typeof t == "object" && t.trace(x, y):
399
				if (this.check_feature("now_playing") && !np_bio) break;
400
				/*_font.AppendMenuItem(MF_STRING, 30, 12);
401
				_font.AppendMenuItem(MF_STRING, 31, 14);
402
				_font.AppendMenuItem(MF_STRING, 32, 16);
403
				_font.AppendTo(_menu, MF_STRING, "Font size");
404
				_font.CheckMenuRadioItem(30, 33, this.normal_font_size == 12 ? 30 : this.normal_font_size == 14 ? 31 : 32);
405
				_menu.AppendMenuSeparator();*/
406
				switch(t.mode) {
407
					case "lastfm_album":
408
						/*_menu.AppendMenuItem(MF_STRING, 53, "Last.fm auto-correct");
409
						_menu.CheckMenuItem(53, l.auto_correct);
410
						_menu.AppendMenuSeparator();*/
411
						break;
412
					case "lastfm_wiki":
413
						/*_menu.AppendMenuItem(MF_STRING, 25, "Last.fm");
414
						_menu.AppendMenuItem(MF_STRING, 26, "Wikipedia");
415
						_menu.CheckMenuRadioItem(25, 26, t.source == "last.fm" ? 25 : 26);
416
						_menu.AppendMenuSeparator();*/
417
						break;
418
					case "simple_tag":
419
						/*_menu.AppendMenuItem(MF_STRING, 1700, "Custom title...");
420
						_menu.AppendMenuItem(MF_STRING, 1701, "Custom tag...");
421
						_menu.AppendMenuSeparator();
422
						_menu.AppendMenuItem(MF_STRING, 1702, "Centre text");
423
						_menu.CheckMenuItem(1702, t.centre);
424
						_menu.AppendMenuSeparator();*/
425
						break;
426
					case "simple_text":
427
						/*_menu.AppendMenuItem(MF_STRING, 1700, "Custom title...");
428
						_menu.AppendMenuItem(MF_STRING, 200, "Custom path...");
429
						_menu.AppendMenuSeparator();
430
						_menu.AppendMenuItem(MF_STRING, 201, "Fixed width font");
431
						_menu.CheckMenuItem(201, t.fixed);
432
						_menu.AppendMenuSeparator();*/
433
						break;
434
				}
435
				break;
436
			case typeof th == "object":
437
			case typeof im == "object" && im.trace(x, y):
438
				if (im.mode == "last.fm") {
439
					/*_menu.AppendMenuItem(this.metadb ? MF_STRING : MF_GRAYED, 450, "Download artist art from Last.fm");
440
					_menu.AppendMenuSeparator();
441
					_sub1.AppendMenuItem(MF_STRING, 451, "Off");
442
					_sub1.AppendMenuItem(MF_STRING, 452, "Library tracks only");
443
					_sub1.AppendMenuItem(MF_STRING, 453, "All tracks");
444
					_sub1.CheckMenuRadioItem(451, 453, im.auto_download == "off" ? 451 : im.auto_download == "library" ? 452 : 453);
445
					//_sub1.AppendTo(_menu, MF_STRING, "Automatic download");
446
					_sub2.AppendMenuItem(MF_STRING, 461, "1");
447
					_sub2.AppendMenuItem(MF_STRING, 463, "3");
448
					_sub2.AppendMenuItem(MF_STRING, 465, "5");
449
					//_sub2.AppendMenuItem(MF_STRING, 470, "10");
450
					//_sub2.AppendMenuItem(MF_STRING, 480, "20");
451
					_sub2.CheckMenuRadioItem(461, 480, im.limit + 460);
452
					//_sub2.AppendTo(_menu, MF_STRING, "Limit");*/
453
                    
454
				} else {
455
					//_menu.AppendMenuItem(MF_STRING, 442, "Set custom folder...");
456
				}
457
var _settings = window.CreatePopupMenu();
458
var _auto_cycle = window.CreatePopupMenu();
459
var _download_source = window.CreatePopupMenu();
460
var _download_limit = window.CreatePopupMenu();
461
var _download_quality = window.CreatePopupMenu();
462
var _thumbs = window.CreatePopupMenu();                
463
var MF_POPUP = 0x00000010;              
464
var MF_GRAYED = 0x00000001;                
465
				//_menu.AppendMenuSeparator();
466
//_menu.AppendMenuItem(MF_STRING, 403, "Auto YT");
467
				//_menu.AppendMenuSeparator();
468
469
470
//Settings Menu
471
//_menu.AppendMenuItem(MF_STRING | MF_POPUP, _settings.ID, "Auto YT");
472
473
//_menu.AppendMenuSeparator();
474
475
//_settings.AppendMenuItem(MF_STRING | MF_POPUP, _auto_cycle.ID, "Auto Cycle");
476
                
477
				//_auto_cycle.AppendMenuItem(MF_STRING, 415, "05 sec");
478
				//_auto_cycle.AppendMenuItem(MF_STRING, 420, "10 sec");
479
				//_auto_cycle.AppendMenuItem(MF_STRING, 425, "15 sec");
480
                //_auto_cycle.AppendMenuItem(MF_STRING, 430, "20 sec");
481
                //_auto_cycle.AppendMenuItem(MF_STRING, 410, "Off");
482
                //_auto_cycle.CheckMenuRadioItem(410, 430, cycle2 + 410);
483
				
484
485
//_settings.AppendMenuItem(MF_STRING | MF_POPUP, _download_source.ID, "Download Source");
486
                  
487
488
                  if(auto_yt==1) _menu.AppendMenuItem(MF_STRING, 1902, "Youtube Radio");
489
                  if(auto_yt==0) _menu.AppendMenuItem(MF_STRING, 1903, "Youtube Radio");
490
                  _menu.CheckMenuItem(1902, auto_yt?1:0);
491
                  
492
                  //if(auto_lfm==1) _menu.AppendMenuItem(MF_STRING, 1905, "Last.fm Radio");
493
                  //if(auto_lfm==0) _menu.AppendMenuItem(MF_STRING, 1906, "Last.fm Radio");
494
                  //_menu.CheckMenuItem(1905, auto_lfm?1:0);
495
                  
496
                  
497
                  _menu.AppendMenuSeparator();
498
499
500
//_settings.AppendMenuItem(MF_STRING | MF_POPUP, _download_limit.ID, "Download Limit");
501
                   
502
                   //_download_limit.AppendMenuItem(MF_STRING, 1905, "1x");
503
                   //_download_limit.AppendMenuItem(MF_STRING, 1906, "2x");
504
                   //_download_limit.AppendMenuItem(MF_STRING, 1907, "3x");
505
                   //_download_limit.AppendMenuItem(MF_STRING, 1908, "4x");
506
                   //_download_limit.AppendMenuItem(MF_STRING, 1909, "5x");
507
                   //_download_limit.AppendMenuItem(MF_STRING, 1910, "6x");
508
                   //_download_limit.CheckMenuRadioItem(1905, 1910, im.limit + 1904);
509
510
511
//if (server=="last.fm") _settings.AppendMenuItem(MF_STRING | MF_POPUP, _download_quality.ID, "Download Quality");
512
                       /*_download_quality.AppendMenuItem(MF_STRING, 1911, "Low");
513
                       _download_quality.AppendMenuItem(MF_STRING, 1912, "Medium");
514
                       _download_quality.AppendMenuItem(MF_STRING, 1913, "High");
515
                       _download_quality.CheckMenuRadioItem(1911, 1913, size == "low" ? 1911 : size == "medium" ? 1912 : size == "high" ? 1913 : 1913);
516
517
518
519
_settings.AppendMenuItem(MF_STRING | MF_POPUP, _thumbs.ID, "Thumbs");
520
                    
521
                    _thumbs.AppendMenuItem(MF_STRING, 1201, "Left");
522
					_thumbs.AppendMenuItem(MF_STRING, 1202, "Right");
523
					_thumbs.AppendMenuItem(MF_STRING, 1203, "Top");
524
					_thumbs.AppendMenuItem(MF_STRING, 1204, "Bottom");
525
					_thumbs.AppendMenuItem(MF_STRING, 1205, "Off");
526
					_thumbs.CheckMenuRadioItem(1200, 1205, th.mode == "grid" ? 1200 : th.mode == "left" ? 1201 : th.mode == "right" ? 1202 : th.mode == "top" ? 1203 : th.mode == "bottom" ? 1204 : 1205);
527
528
529
530
if (th.mode == "left" | th.mode == "right" | th.mode == "top" | th.mode == "bottom")
531
                    {
532
                  _thumbs.AppendMenuSeparator();
533
                  _thumbs.AppendMenuItem(MF_STRING, 1240, "40px");
534
                  _thumbs.AppendMenuItem(MF_STRING, 1250, "50px");
535
                  _thumbs.AppendMenuItem(MF_STRING, 1260, "60px");
536
                  _thumbs.AppendMenuItem(MF_STRING, 1270, "70px");
537
                  _thumbs.AppendMenuItem(MF_STRING, 1280, "80px");
538
                  _thumbs.AppendMenuItem(MF_STRING, 1290, "90px");
539
                  _thumbs.AppendMenuItem(MF_STRING, 1300, "100px");
540
                  _thumbs.AppendMenuItem(MF_STRING, 1350, "150px");
541
                  _thumbs.AppendMenuItem(MF_STRING, 1400, "200px");
542
                  _thumbs.AppendMenuItem(MF_STRING, 1450, "250px");
543
                  _thumbs.AppendMenuItem(MF_STRING, 1500, "300px");
544
                  _thumbs.CheckMenuRadioItem(1240, 1500, th.px + 1200);
545
              }*/
546
547
			/*	_sub3.AppendMenuItem(MF_STRING, 440, "Last.fm artist art");
548
				_sub3.AppendMenuItem(MF_STRING, 441, "Custom folder");
549
				_sub3.CheckMenuRadioItem(440, 441, im.mode == "last.fm" ? 440 : 441);
550
				//_sub3.AppendTo(_menu, MF_STRING, "Image source");
551
               
552
				_menu.AppendMenuSeparator();
553
				/*_sub4.AppendMenuItem(MF_STRING, 410, "Off");
554
				_sub4.AppendMenuItem(MF_STRING, 415, "5 seconds");
555
				_sub4.AppendMenuItem(MF_STRING, 420, "10 seconds");
556
				_sub4.AppendMenuItem(MF_STRING, 430, "20 seconds");
557
				_sub4.CheckMenuRadioItem(410, 430, im.cycle + 410);
558
				_sub4.CheckMenuRadioItem(410, 430, im.cycle + 410);
559
				_menu.AppendMenuSeparator();*/
560
				if (typeof th == "object") {
561
					if (!this.check_feature("now_playing")) _sub5.AppendMenuItem(MF_STRING, 1200, "Grid");
562
					/*_sub5.AppendMenuItem(MF_STRING, 1201, "Left");
563
					_sub5.AppendMenuItem(MF_STRING, 1202, "Right");
564
					_sub5.AppendMenuItem(MF_STRING, 1203, "Top");
565
					_sub5.AppendMenuItem(MF_STRING, 1204, "Bottom");
566
					_sub5.AppendMenuItem(MF_STRING, 1205, "Off");
567
					_sub5.CheckMenuRadioItem(1200, 1205, th.mode == "grid" ? 1200 : th.mode == "left" ? 1201 : th.mode == "right" ? 1202 : th.mode == "top" ? 1203 : th.mode == "bottom" ? 1204 : 1205);*/
568
					if (th.mode != "off") {
569
						/*_sub5.AppendMenuSeparator();
570
						_sub5.AppendMenuItem(MF_STRING, 1275, "75px");
571
						_sub5.AppendMenuItem(MF_STRING, 1300, "100px");
572
						_sub5.AppendMenuItem(MF_STRING, 1350, "150px");
573
						_sub5.AppendMenuItem(MF_STRING, 1400, "200px");
574
						_sub5.AppendMenuItem(MF_STRING, 1450, "250px");
575
						_sub5.AppendMenuItem(MF_STRING, 1500, "300px");
576
						_sub5.CheckMenuRadioItem(1275, 1500, th.px + 1200);*/
577
					}
578
					//_sub5.AppendTo(_menu, MF_STRING, "Thumbs");
579
					//_menu.AppendMenuSeparator();
580
				}
581
				//if (im.trace(x, y) && im.images.length > 0 && (!this.check_feature("thumbs") || th.mode != "grid")) 
582
                {
583
if (auto_yt=="1") _menu.AppendMenuItem(MF_STRING, 22, "Get Next Video");
584
//if (auto_lfm=="1") _menu.AppendMenuItem(MF_STRING, 22, "Get Next Video");
585
if (auto_yt=="0") _menu.AppendMenuItem(MF_STRING, 21, "Get Next Video");
586
//_menu.AppendMenuItem(MF_STRING, 400, "Get All Videos")
587
_menu.AppendMenuItem(MF_STRING, 401, "Search Videos");
588
_menu.AppendMenuSeparator();
589
//_menu.AppendMenuItem(MF_STRING, 402, "Search For Artist");
590
_menu.AppendMenuItem(MF_STRING, 1914, "Start Artist Radio");
591
p.artist = p.eval("%artist%");
592
if (p.artist == "" || p.artist == "?") {_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "Same Artist Radio");}
593
else
594
{_menu.AppendMenuItem(MF_STRING, 1915, "Same Artist Radio");}
595
596
_menu.AppendMenuSeparator();
597
_menu.AppendMenuItem(MF_STRING, 403, "Open Same Video");
598
_menu.AppendMenuItem(MF_STRING, 404, "Find in Browser");
599
					//_menu.AppendMenuItem(MF_STRING, 402, "Delete image");
600
					//_menu.AppendMenuSeparator();
601
					//_menu.AppendMenuItem(MF_STRING, 405, "Top");
602
                    //_menu.AppendMenuItem(MF_STRING, 404, "Centre");
603
					//_menu.AppendMenuItem(MF_STRING, 406, "Adjust");
604
					//_menu.AppendMenuItem(MF_STRING, 407, "Stretch");
605
					_menu.CheckMenuRadioItem(404, 407, im.type == "centre" ? 404 : im.type == "top" ? 405 : im.type == "adjust" ? 406 : 407);
606
					_menu.AppendMenuSeparator();
607
				}
608
				break;
609
		}
610
		if (this.check_feature("now_playing")) {
611
			/*_menu.AppendMenuItem(MF_STRING, 44, "Top style");
612
			_menu.AppendMenuItem(MF_STRING, 45, "Bottom style");
613
			_menu.CheckMenuRadioItem(44, 45, np_track_top ? 44 : 45);
614
			_menu.AppendMenuSeparator();
615
			_menu.AppendMenuItem(MF_STRING, 41, "Show CD cover");
616
			_menu.CheckMenuItem(41, np_cd);
617
			_menu.AppendMenuItem(MF_STRING, 42, "Show track info");
618
			_menu.CheckMenuItem(42, np_track);
619
			_menu.AppendMenuItem(MF_STRING, 46, "Show rating");
620
			_menu.CheckMenuItem(46, np_rating);
621
			_menu.AppendMenuItem(MF_STRING, 40, "Show web links");
622
			_menu.CheckMenuItem(40, np_buttons);
623
			_menu.AppendMenuItem(MF_STRING, 43, "Show biography");
624
			_menu.CheckMenuItem(43, np_bio);
625
			_menu.AppendMenuSeparator();*/
626
		}
627
		if (this.check_feature("custom_background")) {
628
			if (!this.dui) _custom_background.AppendMenuItem(MF_STRING, 100, "None");
629
			/*_custom_background.AppendMenuItem(MF_STRING, 101, this.dui ? "Use default UI setting" : "Use columns UI setting");
630
			_custom_background.AppendMenuItem(MF_STRING, 102, "Splitter");
631
			_custom_background.AppendMenuItem(MF_STRING, 104, "Pattern");
632
			_custom_background.AppendMenuItem(MF_STRING, 103, "Custom");
633
			_custom_background.AppendMenuSeparator();
634
			_custom_background.AppendMenuItem(this.background_mode == 3 ? MF_STRING : MF_GRAYED, 105, "Set custom colour...");
635
			_custom_background.CheckMenuRadioItem(101, 104, this.background_mode + 100);
636
			_custom_background.AppendTo(_menu, MF_STRING, "Background");
637
			_menu.AppendMenuSeparator();*/
638
		}
639
		if (typeof l == "object") {
640
			//_menu.AppendMenuItem(MF_STRING, 1900, "Last.fm username...");
641
			if (typeof ps == "object") _menu.AppendMenuItem(l.username.length > 0 ? MF_STRING : MF_GRAYED, 1901, "Last.fm password...");
642
			//_menu.AppendMenuSeparator();
643
		}
644
		if (this.check_feature("metadb")) {
645
			/*_metadb.AppendMenuItem(MF_STRING, 900, "Use display preferences");
646
			_metadb.AppendMenuItem(MF_STRING, 901, "Prefer now playing");
647
			_metadb.AppendMenuItem(MF_STRING, 902, "Follow selected track");
648
			_metadb.CheckMenuRadioItem(900, 903, this.selection_mode + 900);*/
649
			//_metadb.AppendTo(_menu, MF_STRING, "Selection mode");
650
			//_menu.AppendMenuSeparator();
651
		}
652
		if (this.check_feature("remap")) {
653
			//_menu.AppendMenuItem(MF_STRING, 7, "Artist field remapping...");
654
			//_menu.AppendMenuSeparator();
655
		}
656
		//_menu.AppendMenuItem(MF_STRING, 20, "Update script");
657
		//_menu.AppendMenuSeparator();
658
		//if (utils.IsKeyPressed(0x10)) _menu.AppendMenuItem(MF_STRING, 9, "Properties");
659
        _menu.AppendMenuItem(MF_STRING, 9, "Properties...");
660
        if (utils.IsKeyPressed(0x10)) _menu.AppendMenuItem(MF_STRING, 10, "Configure...");
661
		idx = _menu.TrackPopupMenu(x, y);
662
		switch(idx) {
663
			case 1:
664
				on_item_focus_change();
665
				break;
666
			case 2:
667
			case 3:
668
			case 4:
669
			case 5:
670
			case 6:
671
				a.id = idx - 2;
672
				window.SetProperty("artreader_id", a.id);
673
				on_item_focus_change();
674
				break;
675
			case 7:
676
				this.artist_tf = this.InputBox("The default is %artist%\n\nYou can use the full foobar2000 title formatting syntax here.", "Artist field remapping", this.artist_tf);
677
				if (this.artist_tf == "") this.artist_tf = "%path%";
678
				window.SetProperty("YT Search", this.artist_tf);
679
				on_item_focus_change();
680
				break;
681
			case 9:
682
				window.ShowProperties();
683
				break;
684
			case 10:
685
				window.ShowConfigure();
686
				break;
687
			case 11:
688
				c.gloss = !c.gloss;
689
				window.SetProperty("cd_gloss", c.gloss);
690
				window.Repaint();
691
				break;
692
			case 12:
693
				c.shadow = !c.shadow;
694
				window.SetProperty("cd_shadow", c.shadow);
695
				window.Repaint();
696
				break;
697
			case 15:
698
			case 16:
699
			case 17:
700
			case 18:
701
				a.type = idx == 15 ? "centre" : idx == 16 ? "top" : idx == 17 ? "adjust" : "stretch";
702
				window.SetProperty("artreader_image_type", a.type);
703
				window.RepaintRect(a.x, a.y, a.w, a.h);
704
				break;
705
			case 20:
706
				this.update_script();
707
				break;
708
			case 21:
709
				im.downloadLFM1();
710
                break;
711
			case 22:
712
				im.downloadLFM1();
713
				break;
714
			case 23:
715
				fb.ShowPopupMessage("You can get Album Art Downloader here:\n\nhttp://www.hydrogenaudio.org/forums/index.php?showtopic=57392", this.name);
716
				break;
717
			case 25:
718
			case 26:
719
				t.source = idx == 25 ? "last.fm" : "wikipedia";
720
				window.SetProperty("biography_source", t.source);
721
				t.artist = "";
722
				on_item_focus_change();
723
				break;
724
			case 28:
725
				li.show_timestamp = !li.show_timestamp;
726
				window.SetProperty("show_timestamp", li.show_timestamp);
727
				window.RepaintRect(li.x, li.y, li.w, li.h);
728
				break;
729
			case 29:
730
				li.discogs_match = !li.discogs_match;
731
				window.SetProperty("discogs_match", li.discogs_match);
732
				li.artist = "";
733
				on_item_focus_change();
734
				break;
735
			case 30:
736
			case 31:
737
			case 32:
738
				this.normal_font_size = idx == 30 ? 12 : idx == 31 ? 14 : 16;
739
				window.SetProperty("normal_font_size", this.normal_font_size);
740
				this.font_changed();
741
				break;
742
			case 40:
743
				np_buttons = !np_buttons;
744
				window.SetProperty("np_buttons", np_buttons);
745
				on_size();
746
				window.Repaint();
747
				break;
748
			case 41:
749
				np_cd = !np_cd;
750
				window.SetProperty("np_cd", np_cd);
751
				window.Repaint();
752
				break;
753
			case 42:
754
				np_track = !np_track;
755
				window.SetProperty("np_track", np_track);
756
				on_size();
757
				window.Repaint();
758
				break;
759
			case 43:
760
				np_bio = !np_bio;
761
				window.SetProperty("np_bio", np_bio);
762
				window.Repaint();
763
				break;
764
			case 44:
765
			case 45:
766
				np_track_top = idx == 44 ? true : false;
767
				window.SetProperty("np_track_top", np_track_top);
768
				on_size();
769
				window.Repaint();
770
				break;
771
			case 46:
772
				np_rating = !np_rating;
773
				window.SetProperty("np_rating", np_rating);
774
				on_size();
775
				window.Repaint();
776
				break;
777
			case 51:
778
			case 52:
779
			case 53:
780
				l.auto_correct = !l.auto_correct;
781
				window.SetProperty("lastfm_auto_correct", l.auto_correct);
782
				if (this.metadb) {
783
					if (idx == 51) li.get();
784
					if (idx == 53) t.get();
785
				}
786
				break;
787
			case 100:
788
			case 101:
789
			case 102:
790
			case 103:
791
			case 104:
792
				this.background_mode = idx - 100;
793
				window.SetProperty("background_mode", this.background_mode);
794
				window.Repaint();
795
				break;
796
			case 105:
797
				this.background_custom_colour = this.InputBox("Enter a custom colour for the background. Uses RGB. Example usage:\n\n234-211-74", this.name, this.background_custom_colour);
798
				window.SetProperty("background_custom_colour", this.background_custom_colour);
799
				window.Repaint();
800
				break;
801
			case 200:
802
				t.filename_tf = this.InputBox("Use title formatting to specify a path to your text file. eg: $directory_path(%path%)\\info.txt\n\nIf you prefer, you can specify just the path to a folder and the first txt or log file will be used.", this.name, t.filename_tf);
803
				window.SetProperty("text_filename_tf", t.filename_tf);
804
				on_item_focus_change();
805
				break;
806
			case 201:
807
				t.fixed = !t.fixed;
808
				window.SetProperty("text_fixed_font", t.fixed);
809
				t.calc();
810
				window.RepaintRect(t.x, t.y, t.w, t.h);
811
				break;
812
			case 400:
813
				im.downloadALL();
814
				break;
815
			case 401:
816
				fb.RunMainMenuCommand("View/Youtube Source");
817
				break;
818
			case 402:
819
				im.downloadART();
820
				break;
821
			case 403:
822
				im.downloadART_TITLE();
823
				break;
824
			case 404:
825
            p.artist = p.eval("%artist% %title%");
826
            p.browser("http://www.youtube.com/results?search_query=" + encodeURIComponent(p.artist));
827
            break;
828
			case 405:
829
			case 406:
830
			case 407:
831
				im.type = idx == 404 ? "centre" : idx == 405 ? "top" : idx == 406 ? "adjust" : "stretch";
832
				//window.SetProperty("Image type", im.type);
833
				window.Repaint();
834
				break;
835
			case 410:
836
			case 415:
837
			case 420:
838
			case 425:
839
            case 430:
840
				cycle2 = idx - 410;
841
				window.SetProperty("Image cycle", cycle2);
842
                cicleTimer = undefined;
843
                cicleTimerStarted = false;
844
                stopTimer();
845
                startTimer();
846
                cicleTimerStarted = true;
847
                break;
848
			case 440:
849
			case 441:
850
				im.mode = idx == 440 ? "last.fm" : "custom";
851
				window.SetProperty("image_mode", im.mode);
852
				im.artist = "";
853
				im.folder = "";
854
				on_item_focus_change();
855
				break;
856
			case 442:
857
				im.custom_folder_tf = this.InputBox("Enter title formatting or an absolute path to a folder. You can specify multiple folders using | as a separator.", this.name, im.custom_folder_tf);
858
				if (im.custom_folder_tf == "") im.custom_folder_tf = "$directory_path(%path%)";
859
				window.SetProperty("image_custom_folder_tf", im.custom_folder_tf);
860
				im.folder = "";
861
				on_item_focus_change();
862
				break;
863
			case 450:
864
				im.download();
865
				break;
866
			case 451:
867
			case 452:
868
			case 453:
869
				im.auto_download = idx == 451 ? "on" : idx == 452 ? "library" : "off";
870
				window.SetProperty("image_auto_download", im.auto_download);
871
				break;
872
			case 461:
873
			case 463:
874
			case 465:
875
				im.limit = idx - 460;
876
				window.SetProperty("image_limit", 50);
877
				break;
878
			case 490:
879
			case 491:
880
			case 492:
881
			case 493:
882
				im.type = idx == 490 ? "centre" : idx == 491 ? "top" : idx == 492 ? "adjust" : "stretch";
883
				window.SetProperty("image_type", im.type);
884
				window.RepaintRect(im.x, im.y, im.w, im.h);
885
				break;
886
			case 500:
887
			case 501:
888
			case 502:
889
				li.echonest_mode = idx - 500;
890
				window.SetProperty("echonest_mode", li.echonest_mode);
891
				li.artist = "";
892
				on_item_focus_change();
893
				break;
894
			case 600:
895
				li.autoplaylists_title = this.InputBox("Enter a new title", this.name, li.autoplaylists_title);
896
				if (li.autoplaylists_title == "") li.autoplaylists_title = "Autoplaylists";
897
				window.SetProperty("autoplaylists_title", li.autoplaylists_title);
898
				window.Repaint();
899
				break;
900
			case 601:
901
			case 602:
902
			case 603:
903
			case 604:
904
			case 605:
905
			case 606:
906
			case 607:
907
			case 608:
908
				li.autoplaylists_slot = idx - 600;
909
				window.SetProperty("autoplaylists_slot", li.autoplaylists_slot);
910
				li.filename = this.settings_folder + "autoplaylists" + li.autoplaylists_slot;
911
				li.offset = 0;
912
				li.update();
913
				break;
914
			case 610:
915
			case 611:
916
				li.autoplaylists_success = idx == 610 ? true : false;
917
				window.SetProperty("autoplaylists_success", li.autoplaylists_success);
918
				break;
919
			case 620:
920
			case 621:
921
			case 622:
922
			case 623:
923
			case 624:
924
			case 625:
925
			case 626:
926
			case 627:
927
				li.data.push(li.autoplaylists_deleted_items[idx - 620]);
928
				if (li.data.length > li.rows) li.offset = li.data.length - li.rows;
929
				li.autoplaylists_deleted_items.splice(idx - 620, 1);
930
				this.save(li.data.join("\n"), li.filename);
931
				window.NotifyOthers("autoplaylists", "update");
932
				li.update();
933
				break;
934
			case 650:
935
				li.autoplaylists_remove_duplicates = !li.autoplaylists_remove_duplicates
936
				window.SetProperty("autoplaylists_remove_duplicates", li.autoplaylists_remove_duplicates);
937
				break;
938
			case 700:
939
			case 701:
940
				li.musicbrainz_mode = idx == 700 ? "releases" : "URLs";
941
				window.SetProperty("musicbrainz_mode", li.musicbrainz_mode);
942
				li.artist = "";
943
				on_item_focus_change();
944
				break;
945
			case 702:
946
				li.musicbrainz_album = !li.musicbrainz_album;
947
				window.SetProperty("musicbrainz_album", li.musicbrainz_album);
948
				li.artist = "";
949
				on_item_focus_change();
950
				break;
951
			case 703:
952
				li.musicbrainz_ep = !li.musicbrainz_ep;
953
				window.SetProperty("musicbrainz_ep", li.musicbrainz_ep);
954
				li.artist = "";
955
				on_item_focus_change();
956
				break;
957
			case 704:
958
				li.musicbrainz_single = !li.musicbrainz_single;
959
				window.SetProperty("musicbrainz_single", li.musicbrainz_single);
960
				li.artist = "";
961
				on_item_focus_change();
962
				break;
963
			case 705:
964
				li.musicbrainz_live = !li.musicbrainz_live;
965
				window.SetProperty("musicbrainz_live", li.musicbrainz_live);
966
				li.artist = "";
967
				on_item_focus_change();
968
				break;
969
			case 706:
970
				li.musicbrainz_remix = !li.musicbrainz_remix;
971
				window.SetProperty("musicbrainz_remix", li.musicbrainz_remix);
972
				li.artist = "";
973
				on_item_focus_change();
974
				break;
975
			case 707:
976
				li.musicbrainz_compilation = !li.musicbrainz_compilation;
977
				window.SetProperty("musicbrainz_compilation", li.musicbrainz_compilation);
978
				li.artist = "";
979
				on_item_focus_change();
980
				break;
981
			case 708:
982
				li.musicbrainz_show_release_type = !li.musicbrainz_show_release_type;
983
				window.SetProperty("musicbrainz_show_release_type", li.musicbrainz_show_release_type);
984
				window.RepaintRect(li.x, li.y, li.w, li.h);
985
				break;
986
			case 801:
987
			case 802:
988
			case 803:
989
			case 804:
990
			case 805:
991
				li.lastfm_mode = idx - 801;
992
				window.SetProperty("lastfm_mode", li.lastfm_mode);
993
				li.artist = "";
994
				on_item_focus_change();
995
				break;
996
			case 810:
997
				li.lastfm_pause = !li.lastfm_pause;
998
				window.SetProperty("lastfm_pause", li.lastfm_pause);
999
				break;
1000
			case 811:
1001
			case 812:
1002
				li.lastfm_button = idx == 811 ? "spotify" : "auto";
1003
				window.SetProperty("lastfm_button", li.lastfm_button);
1004
				window.RepaintRect(li.x, li.y, li.w, li.h);
1005
				break;
1006
			case 900:
1007
			case 901:
1008
			case 902:
1009
				this.selection_mode = idx - 900;
1010
				window.SetProperty("selection_mode", this.selection_mode);
1011
				on_item_focus_change();
1012
				break;
1013
			case 1000:
1014
				li.get();
1015
				break;
1016
			case 1001:
1017
			case 1002:
1018
			case 1003:
1019
				li.lastfm_charts_mode = idx - 1001;
1020
				window.SetProperty("lastfm_charts_mode", li.lastfm_charts_mode);
1021
				li.update();
1022
				break;
1023
			case 1004:
1024
			case 1005:
1025
			case 1006:
1026
			case 1007:
1027
			case 1008:
1028
			case 1009:
1029
				li.lastfm_charts_period = idx - 1004;
1030
				window.SetProperty("lastfm_charts_period", li.lastfm_charts_period);
1031
				li.update();
1032
				break;
1033
			case 1010:
1034
				li.lastfm_charts_bar_colour = this.InputBox("Enter a custom colour for the bars. Uses RGB. Example usage:\n\n234-211-74", this.name, li.lastfm_charts_bar_colour);
1035
				window.SetProperty("lastfm_charts_bar_colour", li.lastfm_charts_bar_colour);
1036
				window.Repaint();
1037
				break;
1038
			case 1100:
1039
			case 1109:
1040
				ps.full_import = idx == 1100 ? true : false;
1041
				ps.start_import();
1042
				break;
1043
			case 1101:
1044
				ps.finish_import();
1045
				break;
1046
			case 1102:
1047
				ps.show_console = !ps.show_console;
1048
				window.SetProperty("playcount_sync_show_console", ps.show_console);
1049
				break;
1050
			case 1103:
1051
				ps.library = !ps.library;
1052
				window.SetProperty("playcount_sync_library", ps.library);
1053
				break;
1054
			case 1104:
1055
			case 1105:
1056
				ps.auto_love = idx == 1104 ? false : true;
1057
				window.SetProperty("playcount_sync_auto_love", ps.auto_love);
1058
				break;
1059
			case 1106:
1060
				ps.auto_love_tf = this.InputBox("The result of the title formatting set here must equal 1 for a track to be automatically loved.\n\nExample:\n\n$ifequal(%rating%,5,1,0)", this.name, ps.auto_love_tf);
1061
				window.SetProperty("playcount_sync_auto_love_tf", ps.auto_love_tf);
1062
				break;
1063
			case 1107:
1064
			case 1108:
1065
				ps.icon = idx == 1107 ? "tango" : "silk";
1066
				window.SetProperty("playcount_sync_icon", ps.icon);
1067
				b.update();
1068
				break;
1069
			case 1200:
1070
			case 1201:
1071
			case 1202:
1072
			case 1203:
1073
			case 1204:
1074
			case 1205:
1075
				th.mode = idx == 1200 ? "grid" : idx == 1201 ? "left" : idx == 1202 ? "right" : idx == 1203 ? "top" : idx == 1204 ? "bottom" : "off";
1076
				//window.SetProperty("Thumbs mode", th.mode);
1077
				th.nc = true;
1078
				on_size();
1079
				window.Repaint();
1080
				break;
1081
			case 1240:
1082
			case 1250:
1083
			case 1260:
1084
			case 1270:
1085
			case 1280:
1086
			case 1290:
1087
            case 1300:
1088
			case 1350:
1089
			case 1400:
1090
			case 1450:
1091
			case 1500:
1092
				th.px = idx - 1200;
1093
				
1094
				th.nc = true;
1095
				on_size();
1096
				window.Repaint();
1097
				break;
1098
			case 1700:
1099
				t.title = this.InputBox("You can use full title formatting here.", this.name, t.title);
1100
				window.SetProperty("text_title", t.title);
1101
				window.Repaint();
1102
				break;
1103
			case 1701:
1104
				t.tag = this.InputBox("Enter a custom tag.", this.name, t.tag);
1105
				window.SetProperty("text_tag", t.tag);
1106
				t.filename = "";
1107
				on_item_focus_change();
1108
				break;
1109
			case 1702:
1110
				t.centre = !t.centre;
1111
				window.SetProperty("text_centre", t.centre);
1112
				window.RepaintRect(t.x, t.y, t.w, t.h);
1113
				break;
1114
			case 1800:
1115
			case 1801:
1116
			case 1802:
1117
				var period = idx == 1800 ? 0 : idx == 1801 ? ONE_DAY : ONE_WEEK;
1118
				s.clear_images(period);
1119
				break;
1120
			case 1803:
1121
				s.library = !s.library;
1122
				window.SetProperty("seekbar_library", s.library);
1123
				break;
1124
			case 1804:
1125
				s.sox_params = this.InputBox("All SoX spectrogram options should work here.\n\n-r, -d and -o are already configured so do not use those. Check sox.pdf for everything else.", this.name, s.sox_params);
1126
				window.SetProperty("sox_params", s.sox_params);
1127
				if (fb.IsPlaying) s.playback_new_track();
1128
				break;
1129
			case 1805:
1130
				s.marker = this.InputBox("Enter a custom colour for the marker. Uses RGB. Example usage:\n\n234-211-74", this.name, s.marker);
1131
				window.SetProperty("seekbar_marker", s.marker);
1132
				break;
1133
			case 1900:
1134
				l.update_username();
1135
				break;
1136
			case 1901:
1137
				l.update_password();
1138
				break;
1139
            
1140
                
1141
           case 1902:
1142
                auto_yt = 0;
1143
                window.SetProperty("YT Radio", "0");
1144
                break;
1145
       
1146
           case 1903:
1147
                auto_yt = 1;
1148
                window.SetProperty("YT Radio", "1");
1149
                break; 
1150
  
1151
1152
            case 1904:
1153
            if (server=="on")server = window.SetProperty("YT Radio", "off");
1154
            if (server=="off")server = window.SetProperty("YT Radio", "on");
1155
            break;
1156
1157
            case 1905: 
1158
            auto_lfm = 0;
1159
            window.SetProperty("LFM Radio", "0");
1160
            break;
1161
            
1162
            case 1906:  
1163
             auto_lfm = 1;
1164
             window.SetProperty("LFM Radio", "1");
1165
             break;
1166
            
1167
            case 1907: 
1168
            case 1908:    
1169
            case 1909:    
1170
            case 1910: 
1171
            im.limit = idx - 1904;
1172
            //window.SetProperty("Download limit", im.limit);
1173
            break;
1174
            
1175
            case 1911:    
1176
            case 1912:    
1177
            case 1913: 
1178
            size = idx == 1911 ? "low" : idx == 1912 ? "medium" : idx == 1913 ? "high" : "high";
1179
		    window.SetProperty("Download quality", size);
1180
            break;
1181
            
1182
            case 1914:
1183
            Start = START_ARTIST;
1184
            START_ARTIST = this.InputBox("Type Artist to Start Radio", this.name, START_ARTIST);
1185
            window.SetProperty("Artist Station", START_ARTIST);
1186
            if (START_ARTIST==Start)
1187
            {
1188
            }
1189
            else
1190
            {
1191
            auto_yt = 1;
1192
            window.SetProperty("YT Radio", "1");
1193
            im.downloadLFM0();
1194
            }
1195
            break;
1196
            
1197
            case 1915:
1198
            Start = START_ARTIST;
1199
            p.artist = p.eval("%artist%");
1200
            if (p.artist == "" || p.artist == "?") return;
1201
            START_ARTIST = p.artist;
1202
            window.SetProperty("Artist Station", p.artist);
1203
            auto_yt = 1;
1204
            window.SetProperty("YT Radio", "1");
1205
            on_item_focus_change();
1206
            /*if (START_ARTIST==Start)
1207
            {
1208
            }
1209
            else
1210
            {*/
1211
            im.downloadLFM0();
1212
            //}
1213
            break;
1214
            
1215
            
1216
        }
1217
		_menu.Dispose();
1218
		_custom_background.Dispose();
1219
		_metadb.Dispose();
1220
		_cover.Dispose();
1221
		_font.Dispose();
1222
		_sub1.Dispose();
1223
		_sub2.Dispose();
1224
		_sub3.Dispose();
1225
		_sub4.Dispose();
1226
		_sub5.Dispose();
1227
	}
1228
	
1229
	this.features_init = function() {
1230
		for (i = 0; i < this.features.length; i++) {
1231
			switch(this.features[i]) {
1232
				case "custom_background":
1233
					//this.background_mode = (0);
1234
                    //window.GetProperty("background_mode", 0);
1235
					//this.background_custom_colour = ("0-0-0");
1236
                    //window.GetProperty("background_custom_colour", "0-0-0");
1237
					break;
1238
				case "metadb":
1239
					this.selection_mode = 1;
1240
					break;
1241
				case "themes":
1242
					this.themed_seekbar = window.CreateThemeManager("Progress");
1243
					this.themed_header = window.CreateThemeManager("Header");
1244
					this.themed_header.SetPartAndStateId(1, 1);
1245
					this.themed_button = window.CreateThemeManager("Button");
1246
					break;
1247
				case "remap":
1248
					this.artist_tf = window.GetProperty("YT Search", "%path%");
1249
					break;
1250
			}
1251
		}
1252
	}
1253
	
1254
	this.check_feature = function(f) {
1255
		for (i = 0; i < this.features.length; i++) {
1256
			if (this.features[i] == f) return true;
1257
		}
1258
		return false;
1259
	}
1260
	
1261
	this.eval = function(tf) {
1262
		if (!this.metadb || tf == "") return "";
1263
		if (fb.IsPlaying && this.metadb.RawPath.indexOf("file://") != 0) {
1264
			return fb.TitleFormat(tf).Eval();
1265
		} else {
1266
			return fb.TitleFormat(tf).EvalWithMetadb(this.metadb);
1267
		}
1268
	}
1269
	
1270
	this.open = function(filename) {
1271
		return utils.ReadTextFile(filename);
1272
	}
1273
	
1274
	this.save = function(t, f) {
1275
		try {
1276
			var ts = this.fso.OpenTextFile(f, 2, true, -1);
1277
			ts.WriteLine(t);
1278
			ts.Close();
1279
			return true;
1280
		} catch(e) {
1281
			return false;
1282
		}
1283
	}
1284
	
1285
	this.console = function(message) {
1286
		fb.trace(this.name + ": " + message);
1287
	}
1288
	
1289
	this.strip_tags = function(value) {
1290
		if (!this.doc) this.doc = new ActiveXObject("htmlfile");
1291
		try {
1292
			this.doc.open();
1293
			var div = this.doc.createElement("div");
1294
			div.innerHTML = value.replace(/\n/g, "<br>");
1295
			return div.innerText.trim();
1296
		} catch(e) {
1297
			return "Error reading content.";
1298
		}
1299
	}
1300
	
1301
	this.InputBox = function(prompt, title, value) {
1302
		prompt = prompt.replace(/"/g, '" + Chr(34) + "').replace(/\n/g, '" + Chr(13) + "');
1303
		title = title.replace(/"/g, '" + Chr(34) + "');
1304
		value = value.replace(/"/g, '" + Chr(34) + "');
1305
		var temp_value = this.vb.eval('InputBox' + '("' + prompt + '", "' + title + '", "' + value + '")');
1306
		if (typeof temp_value == "undefined") return value;
1307
		if (temp_value.length == 254) this.MsgBox("Your entry was too long and will be truncated.\n\nSee the WSH panel mod script discussion thread on hydrogenaudio forums for help.", 0, this.name);
1308
		return temp_value.trim();
1309
	}
1310
	
1311
	this.MsgBox = function(prompt, buttons, title) {
1312
		prompt = prompt.replace(/"/g, '" + Chr(34) + "').replace(/\n/g, '" + Chr(13) + "');
1313
		title = title.replace(/"/g, '" + Chr(34) + "');
1314
		return this.vb.eval('MsgBox' + '("' + prompt + '", "' + buttons + '", "' + title + '")');
1315
	}
1316
	
1317
	this.browser = function(command) {
1318
		if (!this.run(command)) this.MsgBox("Unable to launch your default browser.", 0, this.name);
1319
	}
1320
	
1321
	this.run = function(command) {
1322
		try {
1323
			this.WshShell.Run(command);
1324
			return true;
1325
		} catch(e) {
1326
			return false;
1327
		}
1328
	}
1329
	
1330
	this.aad = function() {
1331
		if (!this.app) this.app = new ActiveXObject("Shell.Application");
1332
		var aad_path = window.GetProperty("aad_path", "");
1333
		if (!this.fso.FileExists(aad_path)) {
1334
			var folder = this.app.BrowseForFolder(0, "Locate Album Art Downloader", 0x00000200);
1335
			var file = folder ? folder.items().item().path + "\\AlbumArt.exe" : "";
1336
			if (this.fso.FileExists(file)) {
1337
				aad_path = file;
1338
				window.SetProperty("aad_path", file);
1339
			}
1340
		}
1341
		if (this.fso.FileExists(aad_path)) {
1342
			var album_artist = "/ar \"" + this.eval("[%album artist%]") + "\"";
1343
			var album = " /al \"" + this.eval("[%album%]") + "\"";
1344
			this.run("\"" + aad_path + "\"" + album_artist + album);
1345
		}
1346
	}
1347
	
1348
	this.tt = function(t) {
1349
		if (this.tooltip.Text == t) return;
1350
		this.tooltip.Text = t;
1351
		this.tooltip.Activate();
1352
	}
1353
	
1354
	this.ttd = function() {
1355
		this.tooltip.Text = "";
1356
		this.tooltip.Deactivate();
1357
	}
1358
	
1359
	this.splitRGB = function(value) {
1360
		var temp_col = value.split("-");
1361
		return RGB(temp_col[0], temp_col[1], temp_col[2]);
1362
	}
1363
	
1364
	this.draw_background = function(gr) {
1365
		if (this.check_feature("custom_background")) {
1366
			var col;
1367
			switch(this.background_mode) {
1368
				case 0:
1369
					col = null;
1370
					break;
1371
				case 1:
1372
					col = this.backcolour;
1373
					break;
1374
				case 2:
1375
					col = utils.GetSysColor(15);
1376
					break;
1377
				case 3:
1378
					col = this.splitRGB(this.background_custom_colour);
1379
					break;
1380
				case 4:
1381
					col = null;
1382
					var spacing = 3;
1383
					var line_thickness = 1;
1384
					var bg = RGB(65, 65, 65);
1385
					var colour = RGB(92, 92, 92);
1386
					gr.FillSolidRect(0, 0, this.w, this.h, bg);
1387
					for (i = 0; i < Math.ceil(this.w / spacing); i++) {
1388
						gr.DrawLine(i * spacing, 0, i * spacing, this.h, line_thickness, colour);
1389
					}
1390
					for (i = 0; i < Math.ceil(this.h / spacing); i++) {
1391
						gr.DrawLine(0, i * spacing, this.w, i * spacing, line_thickness, colour);
1392
					}
1393
					break;
1394
			}
1395
			if (col) gr.FillSolidRect(0, 0, this.w, this.h, col);
1396
		} else {
1397
			gr.FillSolidRect(0, 0, this.w, this.h, this.backcolour);
1398
		}
1399
	}
1400
	
1401
	this.draw_image = function(gr, img, pos_x, pos_y, width, height, type, border, alpha) {
1402
		if (!img) return;
1403
		gr.SetInterpolationMode(7);
1404
		switch(type) {
1405
			case "centre":
1406
			  case "top":
1407
               {
1408
                var sr = img.Width / img.Height;
1409
				var dr = width / height;
1410
				if (sr < dr) {
1411
					var r = img.Width / width;
1412
					var ch = height * r;
1413
					var sy = Math.round((img.Height - ch) / (type == "top" ? 1000 : 2));
1414
					var cw = img.Width;
1415
					var sx = 0;
1416
				} else {
1417
                    var r = img.Height / height;
1418
					var cw = width * r;
1419
					var sx = Math.round((img.Width - cw) / 2);
1420
					var ch = img.Height;
1421
					var sy = 0;
1422
				}
1423
                  { 
1424
                   gr.DrawImage(img, pos_x, pos_y, width, height, sx + 5, sy + 5, cw - 10, ch - 10, 0, alpha || 255);
1425
				   if (border) gr.DrawRect(pos_x, pos_y, width - 1, height - 1, 1, border);    
1426
                  }
1427
             }
1428
                break;
1429
			case "stretch":
1430
                //strech
1431
                
1432
                 gr.DrawImage(img, pos_x, pos_y, width, height, 5, 5, img.Width-10, img.Height-10, 0, alpha || 255);
1433
				 if (border) gr.DrawRect(pos_x, pos_y, width - 1, height - 1, 1, border);
1434
                 
1435
                break;
1436
			case "adjust":
1437
			default:
1438
                //adjust
1439
                var s = Math.min(width / img.Width, height / img.Height);
1440
				var nw = Math.round(img.Width * s);
1441
				var nh = Math.round(img.Height * s);
1442
				pos_x += Math.round((width - nw) / 2);
1443
				pos_y += Math.round((height - nh) / 2);
1444
                
1445
                
1446
                gr.DrawImage(img, pos_x, pos_y, nw, nh, 5, 5, img.Width-10, img.Height-10, 0, alpha || 255);
1447
                if (border) gr.DrawRect(pos_x, pos_y, nw - 1, nh - 1, 1, border);
1448
				break;
1449
		
1450
	}
1451
}
1452
	this.header = function(gr, text) {
1453
		this.left_text(gr, text, this.title_font, this.textcolour_hl, 6, 6, this.w - 77, 24);
1454
		gr.DrawLine(6, 29, this.w - 6, 29, 1, this.textcolour_hl);
1455
	}
1456
	
1457
	this.centre_text = function(gr, text, font, colour, x, y, w, h) {
1458
		gr.GdiDrawText(text, font, colour, x, y, w, h, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
1459
	}
1460
	
1461
	this.left_text = function(gr, text, font, colour, x, y, w, h) {
1462
		gr.GdiDrawText(text, font, colour, x, y, w, h, DT_VCENTER | DT_END_ELLIPSIS | DT_CALCRECT | DT_NOPREFIX);
1463
	}
1464
	
1465
	this.right_text = function(gr, text, font, colour, x, y, w, h) {
1466
		gr.GdiDrawText(text, font, colour, x, y, w, h, DT_VCENTER | DT_RIGHT | DT_END_ELLIPSIS | DT_CALCRECT | DT_NOPREFIX);
1467
	}
1468
	
1469
	this.format_time = function(t) {
1470
		var h = Math.floor(t / 3600);
1471
		var m = Math.floor((t -= h * 3600) / 60);
1472
		var s = Math.floor(t -= m * 60);
1473
		return((h > 0 ? h + ":" + (m < 10 ? "0" + m : m) : m) + ":" + (s < 10 ? "0" + s : s));
1474
	}
1475
	
1476
	this.check_version = function() {
1477
		//not used any more but will leave intact so old scripts don't crash.
1478
		return;
1479
	}
1480
	
1481
	this.update_script = function() {
1482
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
1483
		this.xmlhttp.open("GET", this.common_url, true);
1484
		this.xmlhttp.send();
1485
		this.xmlhttp.onreadystatechange = function() {
1486
			if (p.xmlhttp.readyState == 4) {
1487
				switch(p.xmlhttp.status) {
1488
					case 200:
1489
						var text = p.xmlhttp.responsetext;
1490
						switch (true) {
1491
							case text.indexOf("function panel") == -1:
1492
								p.MsgBox("Unexpected server error. Not updating.", 0, p.name);
1493
								break;
1494
							case text.indexOf('var VERSION = "' + VERSION) == 0:
1495
								p.MsgBox("Already using latest version.", 0, p.name);
1496
								break;
1497
							default:
1498
								if (p.save(text, p.common_filename)) {
1499
									if (p.MsgBox("Download successful. Restart foobar2000 now?", 4, p.name) == 6) fb.RunMainMenuCommand("File/Restart");
1500
								} else {
1501
									p.MsgBox("Unexpected error. Not updating.", 0, p.name);
1502
								}
1503
								break;
1504
						}
1505
						break;
1506
					case 404:
1507
						fb.ShowPopupMessage("The script reports that the update file has not been found. It could be a temporary problem with dropbox but if this error persists then it is most likely due to support stopping for this version. Check the hydrogenaudio thread or the full zip for updates.\n\nhttp://www.hydrogenaudio.org/forums/index.php?showtopic=77883\n" + p.root_url + "samples.zip", p.name);
1508
						break;
1509
					default:
1510
						p.console(p.xmlhttp.responsetext || "HTTP error: " + p.xmlhttp.status);
1511
						break;
1512
				}
1513
			}
1514
		}
1515
	}
1516
//remove false string from file names	
1517
    this.clean_filename = function(filename) {
1518
		return filename.replace(/[\/\\|:]/g, '-').replace(/\*/g, 'x').replace(/"/g, "''").replace(/[?<>]/g, '_');
1519
	}
1520
    
1521
    
1522
    
1523
	this.json_parse = function(text) {
1524
		try {
1525
			var data = JSON.parse(text);
1526
			return data;
1527
		} catch(e) {
1528
			this.console("JSON.parse error.");
1529
			return false;
1530
		}
1531
	}
1532
	
1533
	this.name = name;
1534
	this.features = features;
1535
	this.dui = window.InstanceType;
1536
	this.script_path = fb.ProfilePath;
1537
	this.images_path = this.script_path + "images\\";
1538
	this.root_url = "https://dl.dropboxusercontent.com/u/22801321/wsh/"
1539
	this.common_url = this.root_url + "marc2003/common7.js";
1540
	this.common_filename = this.script_path + "common7.js";
1541
	this.tooltip = window.CreateTooltip();
1542
	this.w = 0;
1543
	this.h = 0;
1544
	this.mx = 0;
1545
	this.my = 0;
1546
	this.metadb = fb.GetFocusItem();
1547
	this.WshShell = new ActiveXObject("WScript.Shell");
1548
	this.fso = new ActiveXObject("Scripting.FileSystemObject");
1549
	this.vb = new ActiveXObject("ScriptControl");
1550
	this.vb.Language = "VBScript";
1551
	//this.settings_folder = fb.ProfilePath + "last_fm\\";
1552
	//if (!this.fso.FolderExists(this.settings_folder)) this.fso.CreateFolder(this.settings_folder);
1553
	
1554
    //this.data_folder = lfm_folder + "\\";
1555
    //if (lfm_folder==fb.ProfilePath + "Artist_info") if (!this.fso.FolderExists(this.data_folder)) this.fso.CreateFolder(this.data_folder), this.data_folder=this.data_folder;
1556
    //if (!this.fso.FolderExists(this.data_folder)) return;   
1557
    this.artist = "";
1558
	this.artist_tf = "%path%";
1559
	this.normal_font_size = (12);
1560
    //window.GetProperty("normal_font_size", 12);
1561
	this.list_font_size = 11;
1562
	this.up_img = gdi.Image(this.images_path + "down.png");
1563
	this.down_img = gdi.Image(this.images_path + "down.png");
1564
	this.metadb_func = typeof on_metadb_changed == "function";
1565
	this.features_init();
1566
	this.colors_changed();
1567
	this.font_changed();
1568
}
1569
1570
function artreader(x, y, w, h) {
1571
	this.draw = function(gr) {
1572
		if (!this.img) return;
1573
		p.draw_image(gr, this.img, this.x, this.y, this.w, this.h, this.type);
1574
	}
1575
	
1576
	this.metadb_changed = function() {
1577
		if (!p.metadb) return;
1578
		this.img && this.img.Dispose();
1579
		this.path = "";
1580
		this.img = utils.GetAlbumArtV2(p.metadb, this.id);
1581
		window.RepaintRect(this.x, this.y, this.w, this.h);
1582
		utils.GetAlbumArtAsync(window.ID, p.metadb, this.id);
1583
	}
1584
	
1585
	this.get_album_art_done = function(ip) {
1586
		this.path = ip;
1587
	}
1588
	
1589
	this.trace = function(x, y) {
1590
		return (x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h);
1591
	}
1592
	
1593
	this.wheel = function(step) {
1594
		if (!this.trace(p.mx, p.my)) return false;
1595
		this.id -= step;
1596
		if (this.id < 0) this.id = 4;
1597
		if (this.id > 4) this.id = 0;
1598
		window.SetProperty("artreader_id", this.id);
1599
		this.metadb_changed();
1600
		return true;
1601
	}
1602
	
1603
	this.move = function(x, y) {
1604
		if (this.trace(x, y)) {
1605
			if (this.img) p.tt("Original size: " + this.img.Width + "x" + this.img.Height + "px");
1606
			return true;
1607
		} else {
1608
			p.ttd();
1609
			return false;
1610
		}
1611
	}
1612
	
1613
	this.lbtn_dblclk = function(x, y) {
1614
		if (!this.trace(x, y)) return false;
1615
		if (this.img) p.run("explorer /select,\"" + this.path + "\"");
1616
		return true;
1617
	}
1618
	
1619
	this.x = x;
1620
	this.y = y;
1621
	this.w = w;
1622
	this.h = h;
1623
	this.id = window.GetProperty("artreader_id", 0);
1624
	this.img = null;
1625
	this.path = null;
1626
	this.type = window.GetProperty("artreader_image_type", "top");
1627
}
1628
1629
function buttons() {
1630
	this.draw = function(gr) {
1631
		for (i in this.buttons) {
1632
			this.buttons[i].draw(gr);
1633
		}
1634
	}
1635
	
1636
	this.move = function(x, y) {
1637
		this.tmp_btn = null;
1638
		for (i in this.buttons) {
1639
			if (this.buttons[i].trace(x, y)) this.tmp_btn = i;
1640
		}
1641
		if (this.btn == this.tmp_btn) return this.btn;
1642
		if (this.tmp_btn) this.buttons[this.tmp_btn].state("hover");
1643
		if (this.btn) this.buttons[this.btn].state("normal");
1644
		this.btn = this.tmp_btn;
1645
		return this.btn;
1646
	}
1647
	
1648
	this.lbtn_up = function(x, y) {
1649
		if (!this.btn) return false;
1650
		this.buttons[this.btn].lbtn_up(x, y);
1651
		return true;
1652
	}
1653
	
1654
	this.leave = function() {
1655
		if (this.btn) this.buttons[this.btn].state("normal");
1656
		this.btn = null;
1657
	}
1658
	
1659
	this.buttons = [];
1660
	this.btn = null;
1661
}
1662
1663
function button(x, y, w, h, img_src, func, tiptext, themed) {
1664
	this.draw = function (gr) {
1665
		if (this.themed) {
1666
			p.themed_button.SetPartAndStateId(1, this.id);
1667
			p.themed_button.DrawThemeBackground(gr, this.x, this.y, this.w, this.h);
1668
			this.img && p.draw_image(gr, this.img, this.x + Math.round((this.w - this.img.Width) / 2), this.y + Math.round((this.h - this.img.Height) / 2), this.img.Width, this.img.Height, "adjust");
1669
		} else {
1670
			this.img && p.draw_image(gr, this.img, this.x, this.y, this.w, this.h, "adjust");
1671
		}
1672
	}
1673
	
1674
	this.trace = function(x, y) {
1675
		return (x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h);
1676
	}
1677
	
1678
	this.lbtn_up = function () {
1679
		this.func && this.func(x, y);
1680
	}
1681
	
1682
	this.state = function(s) {
1683
		if (s == "hover") {
1684
			this.img = this.img_hover;
1685
			this.id = 2;
1686
			p.tt(this.tiptext);
1687
		} else {
1688
			this.img = this.img_normal;
1689
			this.id = 0;
1690
			p.ttd();
1691
		}
1692
		window.RepaintRect(this.x, this.y, this.w, this.h);
1693
	}
1694
	
1695
	this.x = x;
1696
	this.y = y;
1697
	this.w = w;
1698
	this.h = h;
1699
	this.func = func;
1700
	this.tiptext = tiptext;
1701
	this.themed = themed;
1702
	this.id = 0;
1703
	this.img_normal = gdi.Image(p.images_path + img_src.normal);
1704
	this.img_hover = img_src.hover ? gdi.Image(p.images_path + img_src.hover) : this.img_normal;
1705
	this.img = this.img_normal;
1706
}
1707
1708
function cd(x, y, w, h) {
1709
	this.draw = function(gr) {
1710
		if (this.shadow) p.draw_image(gr, this.shadow_img, this.x, this.y, this.w, this.h, "adjust");
1711
		p.draw_image(gr, this.case_img, this.x, this.y, this.w, this.h, "adjust");
1712
		if (this.img) {
1713
			this.ratio = Math.min(this.w / this.case_img.Width, this.h / this.case_img.Height);
1714
			this.nw = 488 * this.ratio;
1715
			this.nh = 476 * this.ratio;
1716
			this.nx = Math.round((this.w - (452 * this.ratio)) / 2);
1717
			this.ny = Math.round((this.h - this.nh) / 2);
1718
			p.draw_image(gr, this.img, this.nx + this.x, this.ny + this.y, this.nw, this.nh, "top");
1719
		}
1720
		p.draw_image(gr, this.semi_img, this.x, this.y, this.w, this.h, "adjust");
1721
		if (this.gloss) p.draw_image(gr, this.gloss_img, this.x, this.y, this.w, this.h, "adjust");
1722
	}
1723
	
1724
	this.metadb_changed = function() {
1725
		if (!p.metadb) return;
1726
		this.img && this.img.Dispose();
1727
		this.path = "";
1728
		this.img = utils.GetAlbumArtV2(p.metadb, 0);
1729
		window.Repaint();
1730
		utils.GetAlbumArtAsync(window.ID, p.metadb, 0);
1731
	}
1732
	
1733
	this.get_album_art_done = function(ip) {;
1734
		this.path = ip;
1735
	}
1736
	
1737
	this.trace = function(x, y) {
1738
		return (x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h);
1739
	}
1740
	
1741
	this.move = function(x, y) {
1742
		if (this.trace(x, y)) {
1743
			if (this.img) p.tt("Original size: " + this.img.Width + "x" + this.img.Height + "px");
1744
			return true;
1745
		} else {
1746
			p.ttd();
1747
			return false;
1748
		}
1749
	}
1750
	
1751
	this.lbtn_dblclk = function(x, y) {
1752
		if (!this.trace(x, y)) return false;
1753
		if (this.img) p.run("explorer /select,\"" + this.path + "\"");
1754
		return true;
1755
	}
1756
	
1757
	this.x = x;
1758
	this.y = y;
1759
	this.w = w;
1760
	this.h = h;
1761
	this.shadow_img = gdi.Image(p.images_path + "shadow.png");
1762
	this.case_img = gdi.Image(p.images_path + "case.png");
1763
	this.semi_img = gdi.Image(p.images_path + "semi.png");
1764
	this.gloss_img = gdi.Image(p.images_path + "gloss.png");
1765
	this.gloss = window.GetProperty("cd_gloss", false);
1766
	this.shadow = window.GetProperty("cd_shadow", false);
1767
	this.img = null;
1768
	this.path = null;
1769
}
1770
1771
function images(x, y, w, h) {
1772
	this.playback_time = function(time) {
1773
		if (this.mode == "last.fm" && time == 1 && this.files.length == 0 && p.metadb.RawPath == fb.GetNowPlaying().RawPath && ((this.auto_download == "library" && fb.IsMetadbInMediaLibrary(p.metadb)) || this.auto_download == "on")) this.download();
1774
		if (this.cycle > 0 && this.images.length > 1 && time % this.cycle == 0) {
1775
			this.index++;
1776
			if (this.index == this.images.length) this.index = 0;
1777
			window.RepaintRect(this.x, this.y, this.w, this.h);
1778
		}
1779
	}
1780
	
1781
	this.draw = function (gr) {
1782
		if (this.images.length == 0) return;
1783
		p.draw_image(gr, this.images[this.index], this.x, this.y, this.w, this.h, this.type);
1784
	}
1785
	
1786
	this.metadb_changed = function() {
1787
		if (!p.metadb) return false;
1788
		switch(this.mode) {
1789
			case "last.fm":
1790
				p.artist = p.eval(p.artist_tf);
1791
				if (this.artist == p.artist) return false;
1792
				this.artist = p.artist;
1793
				//this.folder = p.data_folder + p.clean_filename(p.artist);
1794
				//if (!p.fso.FolderExists(this.folder)) p.fso.CreateFolder(this.folder);
1795
				break;
1796
			case "custom":
1797
				this.temp_folder = p.eval(this.custom_folder_tf);
1798
				if (this.temp_folder == this.folder) return false;
1799
				this.folder = this.temp_folder;
1800
				break;
1801
		}
1802
		this.update();
1803
		return true;
1804
	}
1805
	
1806
	this.trace = function(x, y) {
1807
		return (x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h);
1808
	}
1809
	
1810
	this.wheel = function(step) {
1811
		if (!p.metadb || this.images.length < 2 || !this.trace(p.mx, p.my) || (typeof th == "object" && th.mode == "grid" && !th.overlay)) return false;
1812
		this.index -= step;
1813
		if (this.index < 0) this.index = this.images.length - 1;
1814
		if (this.index >= this.images.length) this.index = 0;
1815
		window.RepaintRect(this.x, this.y, this.w, this.h);
1816
		return true;
1817
	}
1818
	
1819
	this.lbtn_dblclk = function(x, y) {
1820
		if (!this.trace(x, y)) return false;
1821
		p.run("\"" + this.files[this.index] + "\"");
1822
		return true;
1823
	}
1824
1825
//LAST.FM RADIO--------------------------------------------------------------------------------------------------
1826
1827
//open simmilar artist
1828
this.downloadLFM = function()
1829
     {
1830
     //if (!p.fso.FolderExists(this.folder))  return;
1831
        {
1832
        if (auto_yt=="1")
1833
       
1834
        {
1835
        if (p.artist.indexOf("3dydfy://")== 0 | p.artist.indexOf("www.youtube.com/")== 0 | p.artist.indexOf("youtube.com/")== 0 | p.artist.indexOf("http://www.youtube.com/")== 0 | p.artist.indexOf("3dydfy://www.youtube.com:80/")== 0 | p.artist.indexOf("www.youtube.com:80/")== 0 | p.artist.indexOf("youtube.com:80/")== 0 | p.artist.indexOf("http://www.youtube.com:80/")== 0)
1836
   
1837
    
1838
    { var randomnumber=Math.floor(Math.random()*18)
1839
      var a=randomnumber;
1840
        this.working=true;
1841
        if (START_ARTIST == "" || START_ARTIST == "?") return;
1842
        //var folder = this.folder + "\\";
1843
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
1844
		this.xmlhttp.open("GET", "http://www.last.fm/music/" + encodeURIComponent(START_ARTIST) + "/+similar"+ "?page=" + a, true);
1845
		this.xmlhttp.send();
1846
		this.xmlhttp.onreadystatechange = function() {
1847
			if (im.xmlhttp.readyState == 4) {
1848
				if (im.xmlhttp.status == 200) {
1849
					var text = im.xmlhttp.responsetext;
1850
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
1851
					im.doc.open();
1852
					var div = im.doc.createElement("div");
1853
					div.innerHTML = text;
1854
					var data = div.getElementsByTagName("a");
1855
					var urls = [];
1856
    
1857
			
1858
1859
for (i = 0; i < data.length; i++) {
1860
    if (data[i].href.indexOf("about:/music/") == 0) urls.push(data[i].href.replace(/about:\//,"").replace("music/","").replace("/_/"," - ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("free-music-downloads","").replace("/+similar?page=2","").replace("/+events","").replace("/+wiki","").replace("-+","").replace("/+albums","").replace("/+tags","").replace("/+images","").replace("/journal","").replace("/charts","").replace("/images","").replace("/listeners","").replace("/similar?page=17","").replace("/news","").replace("/groups","").replace("/albums","").replace("/videos","").replace("/tracks","").replace("/similar","").replace("/tags","").replace("noredirect/","").replace("listeners/+tracks","").replace("videos/+tracks","").replace("/+videos/","").replace("?page=1","").replace("?page=8","").replace("?page=5","").replace("?page=7","").replace("?page=9","").replace("?page=8","").replace(" wiki/edit","").replace("/ similar","").replace("?page=","'").replace("/ charts","'").replace("-","").replace("%2F%E3%82%A4%E3%83%95%E3%83%BB%E3%83%8E%E3%83%83%E3%83%88%E3%83%BB%E3%83%95%E3%82%A9%E3%83%BE3%83%BB%E3%83%A6%E3%83%BC","").replace("Ajoutez ce titre sur Deezer exclusivement sur www.hotmixradio.fr","").replace("www.Hituri.net","").replace("%E3%81%97%E3%82%83%E3%81%AB%E3%82%80%E3%81%AB%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%EF","").replace("%B81%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%EF%B81","").replace("%E4%BD%95%E3%82%88%E3%82%8A%E3%82%82%E5%83%95%E3%82%89%E3%81%97%E3%81%8F%E3%80%81%E4%BD%95%E3%82%88%E3%82%8A","").replace("%E3%82%82%E5%90%9B%E3%82%89%E3%81%97%E3%81%8F","").replace("%D0%91%D1%8D0%B5%D1%82 %D0%BF%D0%BE %D0%B3%D0%BB%D0%B0%D0%B7%D0%B0%D0%BC","").replace("%E3%83%9E%E3%82%A4%E3%83%BB%E3%83%9E3%83%87%E3%82%A3","").replace("%D0%9B%D0%B5%D1%82%D0%B5%D1%82%D1%8C","").replace("%2F%2F %D0%A1%D0%9B%D0%A3%D0%A8%D0%90%D0%AE%D0%A2","").replace("%D0%9F%D0%BE%D0%BF-%D0%A5%D0%B8%D1%82","").replace("/",""));   
1861
}
1862
1863
1864
//select random URL
1865
var randomnumber = Math.floor(Math.random()*(20-50)+50);
1866
do{
1867
randomnumber = Math.floor(Math.random()*(20-50)+50);
1868
} while(randomnumber%2!=1);
1869
i=randomnumber;
1870
1871
1872
//select all url
1873
//for (i = 0; i < urls.length; i++)
1874
{
1875
1876
//do something with urls[i]
1877
p.console("" + urls[i]);
1878
1879
if (urls[i] > "") 
1880
{
1881
1882
last_fm = window.SetProperty("YT Similar", urls[i]);
1883
last_fm = urls[i];
1884
window.SetProperty("YT Similar", urls[i]);
1885
}
1886
else
1887
//if (urls[i] == "" || urls[i] == "?")
1888
{
1889
last_fm = window.SetProperty("YT Similar", "");
1890
last_fm = "";
1891
window.SetProperty("YT Similar", "");
1892
}
1893
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
1894
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\ " + urls[i] + "\"");                   
1895
                    
1896
1897
}
1898
        
1899
                 
1900
             
1901
            
1902
             
1903
//open YT in playlist
1904
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
1905
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
1906
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
1907
1908
1909
                im.doc.close();
1910
                im.working=false;
1911
                if (last_fm == "" || last_fm == "?") {im.downloadLFM();}
1912
                else
1913
                im.downloadTRACK();
1914
				//im.update();
1915
				//window.NotifyOthers("images", "update");
1916
				} else {
1917
					p.console("HTTP error: " + im.xmlhttp.status);
1918
				    if (im.xmlhttp.status == 404)
1919
                    im.downloadLFM();
1920
                }
1921
			}
1922
		}
1923
	}
1924
}}                             
1925
1926
}
1927
1928
1929
//Open track
1930
this.downloadTRACK = function()
1931
     {
1932
     //if (!p.fso.FolderExists(this.folder))  return;
1933
        //if (server==ooo) return true;
1934
        //else
1935
        {
1936
        
1937
1938
        
1939
        
1940
        
1941
        {
1942
        
1943
  
1944
    
1945-
    {var randomnumber=Math.floor(Math.random()*18)
1945+
    {var randomnumber=Math.floor(Math.random()*20)
1946
      var a=randomnumber;
1947
        this.working=true;
1948
        if (last_fm == "" || last_fm == "?") return;
1949
        //var folder = this.folder + "\\";
1950
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
1951
		this.xmlhttp.open("GET", "http://www.last.fm/music/" + encodeURIComponent(last_fm) + "/+tracks" + "?page=" + a, true);
1952
		this.xmlhttp.send();
1953
		this.xmlhttp.onreadystatechange = function() {
1954
			if (im.xmlhttp.readyState == 4) {
1955
				if (im.xmlhttp.status == 200) {
1956
					var text = im.xmlhttp.responsetext;
1957
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
1958
					im.doc.open();
1959
					var div = im.doc.createElement("tr");
1960
					div.innerHTML = text;
1961
					var data = div.getElementsByTagName("td");
1962
					var urls = [];
1963
    
1964
			
1965
1966
for (i = 0; i < data.length; i++) {
1967
    if (data[i].title) urls.push(data[i].title.replace(/about:\//,"").replace(",","").replace("1","").replace("2","").replace("3","").replace("4","").replace("5","").replace("6","").replace("7","").replace("8","").replace("9","").replace("0","").replace("listeners","").replace("listener","").split("(")[0].split("[")[0].split(",")[0].split("{")[0]);
1968
} 
1969
1970
1971
//select random URL
1972-
var randomnumber = Math.floor(Math.random()*50);
1972+
var randomnumber = Math.floor(Math.random()*Math.max(urls.length));
1973
i=randomnumber;
1974
1975
{
1976
1977
//do something with urls[i]
1978
p.console("" + last_fm + " - " + urls[i]);
1979
1980
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
1981
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\ " + urls[i] + "\"");                   
1982
1983
1984
if (urls[i] > "") 
1985
{
1986
1987
ooo2 = window.SetProperty("YT Track", last_fm + " - " + urls[i]);
1988
ooo2 = urls[i];
1989
window.SetProperty("YT Track", last_fm + " - " + urls[i]);
1990
}
1991
else
1992
//if (urls[i] == "" || urls[i] == "?")
1993
{
1994
ooo2 = window.SetProperty("YT Track", "");
1995
ooo2 = "";
1996
window.SetProperty("YT Track", "");
1997
}
1998
}
1999
        
2000
                 
2001
             
2002
            
2003
             
2004
//open YT in playlist
2005
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2006
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2007
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2008
2009
2010
                im.doc.close();
2011
                im.working=false;
2012
                if (ooo2 == "" || ooo2 == "?") {im.downloadLFM();}
2013
                else
2014
                im.downloadYT();
2015
				//im.update();
2016
				//window.NotifyOthers("images", "update");
2017
				} else {
2018
					p.console("HTTP error: " + im.xmlhttp.status);
2019
				    if (im.xmlhttp.status == 404)
2020
                    im.downloadLFM();
2021
                
2022
                }
2023
			}
2024
		}
2025
	}
2026
}}}
2027
2028
		
2029
	
2030
2031
2032
//open Youtube	
2033
this.downloadYT = function()
2034
     {
2035
     //if (!p.fso.FolderExists(this.folder))  return;
2036
        {
2037
        
2038
        //if (server=="last.fm")
2039
        {
2040
        
2041
   //if (p.artist.indexOf("3dydfy://")== 0)
2042
    
2043
    {
2044
        this.working=true;
2045
        if (ooo2 == "" || ooo2 == "?") return;
2046
        //var folder = this.folder + "\\";
2047
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2048
		this.xmlhttp.open("GET", "http://www.youtube.com/results?search_query=" + encodeURIComponent(last_fm) +" - " + encodeURIComponent(ooo2), true);
2049
		this.xmlhttp.send();
2050
		this.xmlhttp.onreadystatechange = function() {
2051
			if (im.xmlhttp.readyState == 4) {
2052
				if (im.xmlhttp.status == 200) {
2053
					var text = im.xmlhttp.responsetext;
2054
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2055
					im.doc.open();
2056
					var div = im.doc.createElement("li");
2057
					div.innerHTML = text;
2058
					var data = div.getElementsByTagName("a");
2059
					var urls = [];
2060
    
2061
			
2062
2063
for (i = 0; i < data.length; i++) {
2064
    if (data[i].href.indexOf("about:/watch?v=") == 0) urls.push("http://www.youtube.com/" + data[i].href.replace(/about:\//,""));
2065
}
2066
2067
//select random URL
2068
//var randomnumber = Math.floor(Math.random()*Math.max(urls.length-1))+1;
2069
//i=randomnumber;
2070
i = 1;
2071
2072
{
2073
2074
//do something with urls[i]
2075
p.console("" + urls[i]);
2076
2077
if (urls[i] > "" && ooo2 > "") 
2078
{
2079
YT_URL = window.SetProperty("YT URL", urls[i]);
2080
YT_URL = urls[i];
2081
window.SetProperty("YT URL", urls[i]);
2082
2083
var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2084
p.run(tmppath+"\\foobar2000.exe /add "+"\ " + urls[i] + "\"");                   
2085
}
2086
else
2087
//if (urls[i] == "" || urls[i] == "?")
2088
{
2089
YT_URL = window.SetProperty("YT URL", "");
2090
YT_URL = "";
2091
window.SetProperty("YT URL", "");
2092
}
2093
2094
2095
2096
 }
2097
        
2098
                 
2099
             
2100
            
2101
             
2102
//open YT in playlist
2103
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2104
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2105
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2106
2107
2108
                im.doc.close();
2109
                im.working=false;
2110
				if (YT_URL == "" || YT_URL == "?") {im.downloadLFM();}
2111
                
2112
				} else {
2113
					p.console("HTTP error: " + im.xmlhttp.status);
2114
                    if (im.xmlhttp.status == 404)
2115
                    im.downloadLFM();
2116
                }
2117
			}
2118
		}
2119
	}
2120
}}}
2121
2122
2123
2124
//LAST.FM RADIO(One)--------------------------------------------------------------------------------------------------
2125
2126
//open simmilar artist
2127
this.downloadLFM1 = function()
2128
     {
2129
     //if (!p.fso.FolderExists(this.folder))  return;
2130
        {
2131
       
2132
        {
2133
        //if (p.artist.indexOf("3dydfy://")== 0 | p.artist.indexOf("www.youtube.com/")== 0 | p.artist.indexOf("youtube.com/")== 0 | p.artist.indexOf("http://www.youtube.com/")== 0 | p.artist.indexOf("3dydfy://www.youtube.com:80/")== 0 | p.artist.indexOf("www.youtube.com:80/")== 0 | p.artist.indexOf("youtube.com:80/")== 0 | p.artist.indexOf("http://www.youtube.com:80/")== 0)
2134
   
2135
    
2136
    { var randomnumber=Math.floor(Math.random()*18)
2137
      var a=randomnumber;
2138
        this.working=true;
2139
        if (START_ARTIST == "" || START_ARTIST == "?") return;
2140
        //var folder = this.folder + "\\";
2141
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2142
		this.xmlhttp.open("GET", "http://www.last.fm/music/" + encodeURIComponent(START_ARTIST) + "/+similar"+ "?page=" + a, true);
2143
		this.xmlhttp.send();
2144
		this.xmlhttp.onreadystatechange = function() {
2145
			if (im.xmlhttp.readyState == 4) {
2146
				if (im.xmlhttp.status == 200) {
2147
					var text = im.xmlhttp.responsetext;
2148
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2149
					im.doc.open();
2150
					var div = im.doc.createElement("div");
2151
					div.innerHTML = text;
2152
					var data = div.getElementsByTagName("a");
2153
					var urls = [];
2154
    
2155
			
2156
2157
for (i = 0; i < data.length; i++) {
2158
     if (data[i].href.indexOf("about:/music/") == 0) urls.push(data[i].href.replace(/about:\//,"").replace("music/","").replace("/_/"," - ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("free-music-downloads","").replace("/+similar?page=2","").replace("/+events","").replace("/+wiki","").replace("-+","").replace("/+albums","").replace("/+tags","").replace("/+images","").replace("/journal","").replace("/charts","").replace("/images","").replace("/listeners","").replace("/similar?page=17","").replace("/news","").replace("/groups","").replace("/albums","").replace("/videos","").replace("/tracks","").replace("/similar","").replace("/tags","").replace("noredirect/","").replace("listeners/+tracks","").replace("videos/+tracks","").replace("/+videos/","").replace("?page=1","").replace("?page=8","").replace("?page=5","").replace("?page=7","").replace("?page=9","").replace("?page=8","").replace(" wiki/edit","").replace("/ similar","").replace("?page=","'").replace("/ charts","'").replace("-","").replace("%2F%E3%82%A4%E3%83%95%E3%83%BB%E3%83%8E%E3%83%83%E3%83%88%E3%83%BB%E3%83%95%E3%82%A9%E3%83%BE3%83%BB%E3%83%A6%E3%83%BC","").replace("Ajoutez ce titre sur Deezer exclusivement sur www.hotmixradio.fr","").replace("www.Hituri.net","").replace("%E3%81%97%E3%82%83%E3%81%AB%E3%82%80%E3%81%AB%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%EF","").replace("%B81%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%EF%B81","").replace("%E4%BD%95%E3%82%88%E3%82%8A%E3%82%82%E5%83%95%E3%82%89%E3%81%97%E3%81%8F%E3%80%81%E4%BD%95%E3%82%88%E3%82%8A","").replace("%E3%82%82%E5%90%9B%E3%82%89%E3%81%97%E3%81%8F","").replace("%D0%91%D1%8D0%B5%D1%82 %D0%BF%D0%BE %D0%B3%D0%BB%D0%B0%D0%B7%D0%B0%D0%BC","").replace("%E3%83%9E%E3%82%A4%E3%83%BB%E3%83%9E3%83%87%E3%82%A3","").replace("%D0%9B%D0%B5%D1%82%D0%B5%D1%82%D1%8C","").replace("%2F%2F %D0%A1%D0%9B%D0%A3%D0%A8%D0%90%D0%AE%D0%A2","").replace("%D0%9F%D0%BE%D0%BF-%D0%A5%D0%B8%D1%82","").replace("/",""));   
2159
}
2160
2161
2162
//select random URL
2163
var randomnumber = Math.floor(Math.random()*(20-50)+50);
2164
do{
2165
randomnumber = Math.floor(Math.random()*(20-50)+50);
2166
} while(randomnumber%2!=1);
2167
i=randomnumber;
2168
2169
//select all url
2170
//for (i = 0; i < urls.length; i++)
2171
{
2172
2173
//do something with urls[i]
2174
p.console("" + urls[i]);
2175
2176
if (urls[i] > "") 
2177
{
2178
2179
last_fm = window.SetProperty("YT Similar", urls[i]);
2180
last_fm = urls[i];
2181
window.SetProperty("YT Similar", urls[i]);
2182
}
2183
else
2184
//if (urls[i] == "" || urls[i] == "?")
2185
{
2186
last_fm = window.SetProperty("YT Similar", "");
2187
last_fm = "";
2188
window.SetProperty("YT Similar", "");
2189
}
2190
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2191
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\ " + urls[i] + "\"");                   
2192
                    
2193
2194
}
2195
        
2196
                 
2197
             
2198
            
2199
             
2200
//open YT in playlist
2201
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2202
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2203
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2204
2205
2206
                im.doc.close();
2207
                im.working=false;
2208
                if (last_fm == "" || last_fm == "?") {im.downloadLFM1();}
2209
                else
2210
                im.downloadTRACK1();
2211
				//im.update();
2212
				//window.NotifyOthers("images", "update");
2213
				} else {
2214
					p.console("HTTP error: " + im.xmlhttp.status);
2215
				    if (im.xmlhttp.status == 404)
2216
                    im.downloadLFM1();
2217
                }
2218
			}
2219
		}
2220
	}
2221
}}                             
2222
2223
}
2224
2225
2226
//Open track
2227
this.downloadTRACK1 = function()
2228
     {
2229
     //if (!p.fso.FolderExists(this.folder))  return;
2230
        //if (server==ooo) return true;
2231
        //else
2232
        {
2233
        
2234
2235
        
2236
        
2237
        
2238
        {
2239
        
2240
  
2241
    
2242-
    {var randomnumber=Math.floor(Math.random()*18)
2242+
    {var randomnumber=Math.floor(Math.random()*20)
2243
      var a=randomnumber;
2244
        this.working=true;
2245
        if (last_fm == "" || last_fm == "?") return;
2246
        //var folder = this.folder + "\\";
2247
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2248
		this.xmlhttp.open("GET", "http://www.last.fm/music/" + encodeURIComponent(last_fm) + "/+tracks" + "?page=" + a, true);
2249
		this.xmlhttp.send();
2250
		this.xmlhttp.onreadystatechange = function() {
2251
			if (im.xmlhttp.readyState == 4) {
2252
				if (im.xmlhttp.status == 200) {
2253
					var text = im.xmlhttp.responsetext;
2254
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2255
					im.doc.open();
2256
					var div = im.doc.createElement("tr");
2257
					div.innerHTML = text;
2258
					var data = div.getElementsByTagName("td");
2259
					var urls = [];
2260
    
2261
			
2262
2263
for (i = 0; i < data.length; i++) {
2264
    if (data[i].title) urls.push(data[i].title.replace(/about:\//,"").replace(",","").replace("1","").replace("2","").replace("3","").replace("4","").replace("5","").replace("6","").replace("7","").replace("8","").replace("9","").replace("0","").replace("listeners","").replace("listener","").split("(")[0].split("[")[0].split(",")[0].split("{")[0]);
2265
}
2266
2267
//select random URL
2268-
var randomnumber = Math.floor(Math.random()*50);
2268+
var randomnumber = Math.floor(Math.random()*Math.max(urls.length));
2269
i=randomnumber;
2270
2271
{
2272
2273
//do something with urls[i]
2274
p.console("" + last_fm + " - " + urls[i]);
2275
2276
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2277
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\ " + urls[i] + "\"");                   
2278
2279
2280
if (urls[i] > "") 
2281
{
2282
2283
ooo2 = window.SetProperty("YT Track", last_fm + " - " + urls[i]);
2284
ooo2 = urls[i];
2285
window.SetProperty("YT Track", last_fm + " - " + urls[i]);
2286
}
2287
else
2288
//if (urls[i] == "" || urls[i] == "?")
2289
{
2290
ooo2 = window.SetProperty("YT Track", "");
2291
ooo2 = "";
2292
window.SetProperty("YT Track", "");
2293
}
2294
}
2295
        
2296
                 
2297
             
2298
            
2299
             
2300
//open YT in playlist
2301
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2302
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2303
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2304
2305
2306
                im.doc.close();
2307
                im.working=false;
2308
                if (ooo2 == "" || ooo2 == "?") {im.downloadLFM1();}
2309
                else
2310
                im.downloadYT1();
2311
				//im.update();
2312
				//window.NotifyOthers("images", "update");
2313
				} else {
2314
					p.console("HTTP error: " + im.xmlhttp.status);
2315
				    if (im.xmlhttp.status == 404)
2316
                    im.downloadLFM1();
2317
                
2318
                }
2319
			}
2320
		}
2321
	}
2322
}}}
2323
2324
		
2325
	
2326
2327
2328
//open Youtube	
2329
this.downloadYT1 = function()
2330
     {
2331
     //if (!p.fso.FolderExists(this.folder))  return;
2332
        {
2333
        
2334
        //if (server=="last.fm")
2335
        {
2336
        
2337
   //if (p.artist.indexOf("3dydfy://")== 0)
2338
    
2339
    {
2340
        this.working=true;
2341
        if (ooo2 == "" || ooo2 == "?") return;
2342
        //var folder = this.folder + "\\";
2343
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2344
		this.xmlhttp.open("GET", "http://www.youtube.com/results?search_query=" + encodeURIComponent(last_fm) +" - " + encodeURIComponent(ooo2), true);
2345
		this.xmlhttp.send();
2346
		this.xmlhttp.onreadystatechange = function() {
2347
			if (im.xmlhttp.readyState == 4) {
2348
				if (im.xmlhttp.status == 200) {
2349
					var text = im.xmlhttp.responsetext;
2350
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2351
					im.doc.open();
2352
					var div = im.doc.createElement("li");
2353
					div.innerHTML = text;
2354
					var data = div.getElementsByTagName("a");
2355
					var urls = [];
2356
    
2357
			
2358
2359
for (i = 0; i < data.length; i++) {
2360
    if (data[i].href.indexOf("about:/watch?v=") == 0) urls.push("http://www.youtube.com/" + data[i].href.replace(/about:\//,""));
2361
}
2362
2363
//select random URL
2364
//var randomnumber = Math.floor(Math.random()*Math.max(urls.length-1))+1;
2365
//i=randomnumber;
2366
i = 1;
2367
2368
{
2369
2370
//do something with urls[i]
2371
p.console("" + urls[i]);
2372
2373
if (urls[i] > "" && ooo2 > "") 
2374
{
2375
YT_URL = window.SetProperty("YT URL", urls[i]);
2376
YT_URL = urls[i];
2377
window.SetProperty("YT URL", urls[i]);
2378
2379
var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2380
p.run(tmppath+"\\foobar2000.exe /add "+"\ " + urls[i] + "\"");                   
2381
}
2382
else
2383
//if (urls[i] == "" || urls[i] == "?")
2384
{
2385
YT_URL = window.SetProperty("YT URL", "");
2386
YT_URL = "";
2387
window.SetProperty("YT URL", "");
2388
}
2389
2390
2391
2392
 }
2393
        
2394
                 
2395
             
2396
            
2397
             
2398
//open YT in playlist
2399
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2400
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2401
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2402
2403
2404
                im.doc.close();
2405
                im.working=false;
2406
				if (YT_URL == "" || YT_URL == "?") {im.downloadLFM1();}
2407
                
2408
				} else {
2409
					p.console("HTTP error: " + im.xmlhttp.status);
2410
                    if (im.xmlhttp.status == 404)
2411
                    im.downloadLFM1();
2412
                }
2413
			}
2414
		}
2415
	}
2416
}}}
2417
2418
2419
2420
//CHECK IF ARTIST EXIST--------------------------------------------------------------------------------------------------
2421
2422
this.downloadLFM0 = function()
2423
    
2424
    {   
2425
        this.working=true;
2426
        if (START_ARTIST == "" || START_ARTIST == "?") return;
2427
        //var folder = this.folder + "\\";
2428
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2429
		this.xmlhttp.open("GET", "http://www.last.fm/music/" + encodeURIComponent(START_ARTIST) + "/+similar", true);
2430
		this.xmlhttp.send();
2431
		this.xmlhttp.onreadystatechange = function() {
2432
			if (im.xmlhttp.readyState == 4) {
2433
				if (im.xmlhttp.status == 200) {
2434
					var text = im.xmlhttp.responsetext;
2435
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2436
					im.doc.open();
2437
					var div = im.doc.createElement("div");
2438
					div.innerHTML = text;
2439
					var data = div.getElementsByTagName("a");
2440
					var urls = [];
2441
    
2442
			
2443
2444
2445
                im.doc.close();
2446
                im.working=false;
2447
                im.downloadLFM000();
2448
				
2449
				} else {
2450
					p.console("HTTP error: " + im.xmlhttp.status);
2451
                    if (im.xmlhttp.status == 404)
2452
                    {
2453
                    p.MsgBox("This Artist Not Exist!", 0, p.name);
2454
                    }
2455
                    
2456
                    
2457
                }
2458
			}
2459
		}
2460
	}
2461
                             
2462
2463
2464
//START ARTIST RADIO(same artist)--------------------------------------------------------------------------------------------------
2465
2466
//open simmilar artist
2467
this.downloadLFM000 = function()
2468
     {
2469
     //if (!p.fso.FolderExists(this.folder))  return;
2470
        {
2471
       
2472
        {
2473
        //if (p.artist.indexOf("3dydfy://")== 0 | p.artist.indexOf("www.youtube.com/")== 0 | p.artist.indexOf("youtube.com/")== 0 | p.artist.indexOf("http://www.youtube.com/")== 0 | p.artist.indexOf("3dydfy://www.youtube.com:80/")== 0 | p.artist.indexOf("www.youtube.com:80/")== 0 | p.artist.indexOf("youtube.com:80/")== 0 | p.artist.indexOf("http://www.youtube.com:80/")== 0)
2474
   
2475
    
2476
    { var randomnumber=Math.floor(Math.random()*18)
2477
      var a=randomnumber;
2478
        this.working=true;
2479
        if (START_ARTIST == "" || START_ARTIST == "?") return;
2480
        //var folder = this.folder + "\\";
2481
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2482
		this.xmlhttp.open("GET", "http://www.last.fm/music/" + encodeURIComponent(START_ARTIST) + "/+similar"+ "?page=" + a, true);
2483
		this.xmlhttp.send();
2484
		this.xmlhttp.onreadystatechange = function() {
2485
			if (im.xmlhttp.readyState == 4) {
2486
				if (im.xmlhttp.status == 200) {
2487
					var text = im.xmlhttp.responsetext;
2488
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2489
					im.doc.open();
2490
					var div = im.doc.createElement("div");
2491
					div.innerHTML = text;
2492
					var data = div.getElementsByTagName("a");
2493
					var urls = [];
2494
    
2495
			
2496
2497
for (i = 0; i < data.length; i++) {
2498
     if (data[i].href.indexOf("about:/music/") == 0) urls.push(data[i].href.replace(/about:\//,"").replace("music/","").replace("/_/"," - ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("+"," ").replace("free-music-downloads","").replace("/+similar?page=2","").replace("/+events","").replace("/+wiki","").replace("-+","").replace("/+albums","").replace("/+tags","").replace("/+images","").replace("/journal","").replace("/charts","").replace("/images","").replace("/listeners","").replace("/similar?page=17","").replace("/news","").replace("/groups","").replace("/albums","").replace("/videos","").replace("/tracks","").replace("/similar","").replace("/tags","").replace("noredirect/","").replace("listeners/+tracks","").replace("videos/+tracks","").replace("/+videos/","").replace("?page=1","").replace("?page=8","").replace("?page=5","").replace("?page=7","").replace("?page=9","").replace("?page=8","").replace(" wiki/edit","").replace("/ similar","").replace("?page=","'").replace("/ charts","'").replace("-","").replace("%2F%E3%82%A4%E3%83%95%E3%83%BB%E3%83%8E%E3%83%83%E3%83%88%E3%83%BB%E3%83%95%E3%82%A9%E3%83%BE3%83%BB%E3%83%A6%E3%83%BC","").replace("Ajoutez ce titre sur Deezer exclusivement sur www.hotmixradio.fr","").replace("www.Hituri.net","").replace("%E3%81%97%E3%82%83%E3%81%AB%E3%82%80%E3%81%AB%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%EF","").replace("%B81%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%EF%B81","").replace("%E4%BD%95%E3%82%88%E3%82%8A%E3%82%82%E5%83%95%E3%82%89%E3%81%97%E3%81%8F%E3%80%81%E4%BD%95%E3%82%88%E3%82%8A","").replace("%E3%82%82%E5%90%9B%E3%82%89%E3%81%97%E3%81%8F","").replace("%D0%91%D1%8D0%B5%D1%82 %D0%BF%D0%BE %D0%B3%D0%BB%D0%B0%D0%B7%D0%B0%D0%BC","").replace("%E3%83%9E%E3%82%A4%E3%83%BB%E3%83%9E3%83%87%E3%82%A3","").replace("%D0%9B%D0%B5%D1%82%D0%B5%D1%82%D1%8C","").replace("%2F%2F %D0%A1%D0%9B%D0%A3%D0%A8%D0%90%D0%AE%D0%A2","").replace("%D0%9F%D0%BE%D0%BF-%D0%A5%D0%B8%D1%82","").replace("/",""));   
2499
}
2500
2501
2502
//select random URL
2503
var randomnumber = Math.floor(Math.random()*(20-50)+50);
2504
do{
2505
randomnumber = Math.floor(Math.random()*(20-50)+50);
2506
} while(randomnumber%2!=1);
2507
i=randomnumber;
2508
2509
//select all url
2510
//for (i = 0; i < urls.length; i++)
2511
{
2512
2513
//do something with urls[i]
2514
p.console("" + urls[i]);
2515
2516
if (urls[i] > "") 
2517
{
2518
2519
last_fm = window.SetProperty("YT Similar", urls[i]);
2520
last_fm = urls[i];
2521
window.SetProperty("YT Similar", urls[i]);
2522
}
2523
else
2524
//if (urls[i] == "" || urls[i] == "?")
2525
{
2526
last_fm = window.SetProperty("YT Similar", "");
2527
last_fm = "";
2528
window.SetProperty("YT Similar", "");
2529
}
2530
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2531
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\ " + urls[i] + "\"");                   
2532
                    
2533
2534
}
2535
        
2536
                 
2537
             
2538
            
2539
             
2540
//open YT in playlist
2541
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2542
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2543
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2544
2545
2546
                im.doc.close();
2547
                im.working=false;
2548
                if (last_fm == "" || last_fm == "?") {im.downloadLFM000();}
2549
                else
2550
                im.downloadTRACK11();
2551
				//im.update();
2552
				//window.NotifyOthers("images", "update");
2553
				} else {
2554
					p.console("HTTP error: " + im.xmlhttp.status);
2555
				    if (im.xmlhttp.status == 404)
2556
                    im.downloadLFM000();
2557
                }
2558
			}
2559
		}
2560
	}
2561
}}                             
2562
2563
}
2564
2565
2566
//Open track
2567
this.downloadTRACK11 = function()
2568
     {
2569
     //if (!p.fso.FolderExists(this.folder))  return;
2570
        //if (server==ooo) return true;
2571
        //else
2572
        {
2573
        
2574
2575
        
2576
        
2577
        
2578
        {
2579
        
2580
  
2581
    
2582-
    {var randomnumber=Math.floor(Math.random()*18)
2582+
    {var randomnumber=Math.floor(Math.random()*20)
2583
      var a=randomnumber;
2584
        this.working=true;
2585
        if (last_fm == "" || last_fm == "?") return;
2586
        //var folder = this.folder + "\\";
2587
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2588
		this.xmlhttp.open("GET", "http://www.last.fm/music/" + encodeURIComponent(last_fm) + "/+tracks" + "?page=" + a, true);
2589
		this.xmlhttp.send();
2590
		this.xmlhttp.onreadystatechange = function() {
2591
			if (im.xmlhttp.readyState == 4) {
2592
				if (im.xmlhttp.status == 200) {
2593
					var text = im.xmlhttp.responsetext;
2594
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2595
					im.doc.open();
2596
					var div = im.doc.createElement("tr");
2597
					div.innerHTML = text;
2598
					var data = div.getElementsByTagName("td");
2599
					var urls = [];
2600
    
2601
			
2602
2603
for (i = 0; i < data.length; i++) {
2604
    if (data[i].title) urls.push(data[i].title.replace(/about:\//,"").replace(",","").replace("1","").replace("2","").replace("3","").replace("4","").replace("5","").replace("6","").replace("7","").replace("8","").replace("9","").replace("0","").replace("listeners","").replace("listener","").split("(")[0].split("[")[0].split(",")[0].split("{")[0]);
2605
}
2606
2607
//select random URL
2608-
var randomnumber = Math.floor(Math.random()*50);
2608+
var randomnumber = Math.floor(Math.random()*Math.max(urls.length));
2609
i=randomnumber;
2610
2611
{
2612
2613
//do something with urls[i]
2614
p.console("" + last_fm + " - " + urls[i]);
2615
2616
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2617
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\ " + urls[i] + "\"");                   
2618
2619
2620
if (urls[i] > "") 
2621
{
2622
2623
ooo2 = window.SetProperty("YT Track", last_fm + " - " + urls[i]);
2624
ooo2 = urls[i];
2625
window.SetProperty("YT Track", last_fm + " - " + urls[i]);
2626
}
2627
else
2628
//if (urls[i] == "" || urls[i] == "?")
2629
{
2630
ooo2 = window.SetProperty("YT Track", "");
2631
ooo2 = "";
2632
window.SetProperty("YT Track", "");
2633
}
2634
}
2635
        
2636
                 
2637
             
2638
            
2639
             
2640
//open YT in playlist
2641
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2642
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2643
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2644
2645
2646
                im.doc.close();
2647
                im.working=false;
2648
                if (ooo2 == "" || ooo2 == "?") {im.downloadLFM000();}
2649
                else
2650
                im.downloadYT11();
2651
				//im.update();
2652
				//window.NotifyOthers("images", "update");
2653
				} else {
2654
					p.console("HTTP error: " + im.xmlhttp.status);
2655
				    if (im.xmlhttp.status == 404)
2656
                    im.downloadLFM000();
2657
                
2658
                }
2659
			}
2660
		}
2661
	}
2662
}}}
2663
2664
		
2665
	
2666
2667
2668
//open Youtube	
2669
this.downloadYT11 = function()
2670
     {
2671
     //if (!p.fso.FolderExists(this.folder))  return;
2672
        {
2673
        
2674
        //if (server=="last.fm")
2675
        {
2676
        
2677
   //if (p.artist.indexOf("3dydfy://")== 0)
2678
    
2679
    {
2680
        this.working=true;
2681
        if (ooo2 == "" || ooo2 == "?") return;
2682
        //var folder = this.folder + "\\";
2683
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2684
		this.xmlhttp.open("GET", "http://www.youtube.com/results?search_query=" + encodeURIComponent(last_fm) +" - " + encodeURIComponent(ooo2), true);
2685
		this.xmlhttp.send();
2686
		this.xmlhttp.onreadystatechange = function() {
2687
			if (im.xmlhttp.readyState == 4) {
2688
				if (im.xmlhttp.status == 200) {
2689
					var text = im.xmlhttp.responsetext;
2690
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2691
					im.doc.open();
2692
					var div = im.doc.createElement("li");
2693
					div.innerHTML = text;
2694
					var data = div.getElementsByTagName("a");
2695
					var urls = [];
2696
    
2697
			
2698
2699
for (i = 0; i < data.length; i++) {
2700
    if (data[i].href.indexOf("about:/watch?v=") == 0) urls.push("http://www.youtube.com/" + data[i].href.replace(/about:\//,""));
2701
}
2702
2703
//select random URL
2704
//var randomnumber = Math.floor(Math.random()*Math.max(urls.length-1))+1;
2705
//i=randomnumber;
2706
i = 1;
2707
2708
{
2709
2710
//do something with urls[i]
2711
p.console("" + urls[i]);
2712
2713
if (urls[i] > "" && ooo2 > "") 
2714
{
2715
YT_URL = window.SetProperty("YT URL", urls[i]);
2716
YT_URL = urls[i];
2717
window.SetProperty("YT URL", urls[i]);
2718
2719
var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2720
p.run(tmppath+"\\foobar2000.exe /add "+"\ " + urls[i] + "\"");                   
2721
}
2722
else
2723
//if (urls[i] == "" || urls[i] == "?")
2724
{
2725
YT_URL = window.SetProperty("YT URL", "");
2726
YT_URL = "";
2727
window.SetProperty("YT URL", "");
2728
}
2729
2730
2731
2732
 }
2733
        
2734
                 
2735
             
2736
            
2737
             
2738
//open YT in playlist
2739
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2740
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2741
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2742
2743
2744
                im.doc.close();
2745
                im.working=false;
2746
				if (YT_URL == "" || YT_URL == "?") {im.downloadLFM000();}
2747
                
2748
				} else {
2749
					p.console("HTTP error: " + im.xmlhttp.status);
2750
                    if (im.xmlhttp.status == 404)
2751
                    im.downloadLFM000();
2752
                }
2753
			}
2754
		}
2755
	}
2756
}}}
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
//Download Same Video------------------------------------------------------------------
2767
this.downloadART_TITLE = function()
2768
     {
2769
   
2770
        {
2771
        
2772
        
2773
        {
2774
        
2775
  
2776
    
2777
    {
2778
        this.working=true;
2779
        p.artist = p.eval("%artist% %title%");
2780
        if (p.artist == "" || p.artist == "?") return;
2781
        var folder = this.folder + "\\";
2782
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2783
		this.xmlhttp.open("GET", "http://www.youtube.com/results?search_query=" + encodeURIComponent(p.artist), true);
2784
		this.xmlhttp.send();
2785
		this.xmlhttp.onreadystatechange = function() {
2786
			if (im.xmlhttp.readyState == 4) {
2787
				if (im.xmlhttp.status == 200) {
2788
					var text = im.xmlhttp.responsetext;
2789
					if (!im.doc) im.doc = new ActiveXObject("htmlfile");
2790
					im.doc.open();
2791
					var div = im.doc.createElement("li");
2792
					div.innerHTML = text;
2793
					var data = div.getElementsByTagName("a");
2794
					var urls = [];
2795
    
2796
			
2797
2798
for (i = 0; i < data.length; i++) {
2799
    if (data[i].href.indexOf("about:/watch?v=") == 0) urls.push("http://www.youtube.com/" + data[i].href.replace(/about:\//,""));
2800
}
2801
2802
//select random URL
2803
//var randomnumber = Math.floor(Math.random()*Math.max(urls.length-1))+1;
2804
//i=randomnumber;
2805
//i = Math.min(urls.length-38);
2806
i=1;
2807
{
2808
2809
//do something with urls[i]
2810
p.console("" + urls[i]);
2811
2812
var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2813
p.run(tmppath+"\\foobar2000.exe /add "+"\ " + urls[i] + "\"");                   
2814
                    
2815
2816
}
2817
        
2818
                 
2819
             
2820
            
2821
             
2822
//open YT in playlist
2823
//var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
2824
//p.run(tmppath+"\\foobar2000.exe /immediate /add "+"\""+urls[i] + "\"");
2825
//fb.RunMainMenuCommand("File/Add Youtube URL(s)...") + ("/immediate /add "+"\""+ urls[i]);                       
2826
2827
2828
                im.doc.close();
2829
                im.working=false;
2830
				im.update();
2831
				window.NotifyOthers("images", "update");
2832
				} else {
2833
					p.console("HTTP error: " + im.xmlhttp.status);
2834
				}
2835
			}
2836
		}
2837
	}
2838
}}}
2839
2840
2841
2842
2843
2844
2845
this.update0 = function() {
2846
		this.index = 0;
2847
		for (i = 0; i < this.images.length; i++) {
2848
			try { this.images[i].Dispose(); } catch(e) {}
2849
		}
2850
		this.folders = this.folder.split("|");
2851
		this.files = [];
2852
		for (i = 0; i < this.folders.length; i++) {
2853
			if (p.fso.FolderExists(this.folders[i])) this.files = this.files.concat(utils.Glob(this.folders[i] + "\\" + p.clean_filename(p.artist) + "_0" + "*.jpg").toArray(), utils.Glob(this.folders[i] + "\\" + p.clean_filename(p.artist) + "_0" + "*.jpeg").toArray(), utils.Glob(this.folders[i] + "\\" + p.clean_filename(p.artist) + "_0" + "*.png").toArray(), utils.Glob(this.folders[i] + "\\" + p.clean_filename(p.artist) + "_0" + "*.gif").toArray());
2854
		}
2855
		this.images = [];
2856
		for (i = 0; i < this.files.length; i++) {
2857
			this.images[i] = gdi.Image(this.files[i]);
2858
		}
2859
		if (typeof th == "object") {
2860
			th.nc = true;
2861
			th.calc();
2862
		}
2863
		window.Repaint();
2864
	}  
2865
    
2866
    
2867
    
2868
	this.update = function() {
2869
		this.index = 0;
2870
		for (i = 0; i < this.images.length; i++) {
2871
			try { this.images[i].Dispose(); } catch(e) {}
2872
		}
2873
		this.folders = this.folder.split("|");
2874
		this.files = [];
2875
		for (i = 0; i < this.folders.length; i++) {
2876
			if (p.fso.FolderExists(this.folders[i])) this.files = this.files.concat(utils.Glob(this.folders[i] + "\\*.jpg").toArray(), utils.Glob(this.folders[i] + "\\*.jpeg").toArray(), utils.Glob(this.folders[i] + "\\*.png").toArray(), utils.Glob(this.folders[i] + "\\*.gif").toArray());
2877
		}
2878
2879
		this.images = [];
2880
		for (i = 0; i < this.files.length; i++) {
2881
			this.images[i] = gdi.Image(this.files[i]);
2882
		}
2883
		if (typeof th == "object") {
2884
			th.nc = true;
2885
			th.calc();
2886
		}
2887
		window.Repaint();
2888
	}
2889
	
2890
	this.delete_image = function() {
2891
		if (!this.app) this.app = new ActiveXObject("Shell.Application");
2892
		this.app.Namespace(10).MoveHere(this.files[this.index]);
2893
        window.SetTimeout(function() {
2894
			im.update();
2895
			window.NotifyOthers("images", "update");
2896
		}, 100);
2897
	}
2898
	
2899
	this.x = x;
2900
	this.y = y;
2901
	this.w = w;
2902
	this.h = h;
2903
	this.files = [];
2904
	this.images = [];
2905
	this.index = 0;
2906
	this.artist = "";
2907
	this.folder = "";
2908
	this.limit = 0;
2909
	//this.cycle = window.GetProperty("image_cycle", 0);
2910
	this.mode = ("last.fm");
2911
    //window.GetProperty("image_mode", "last.fm");
2912
	this.type = "adjust";
2913
	this.auto_download = "off";
2914
	this.custom_folder_tf = "$directory_path(%path%)";
2915
}
2916
2917
function lastfm() {
2918
	this.notify_data = function(name, data) {
2919
		if (name == "lastfm" && data == "update") {
2920
			this.username = p.open(this.username_file).trim();
2921
			this.sk = p.open(this.sk_file).trim();
2922
			if (p.check_feature("lastfm_charts")) li.update();
2923
			if (typeof ps == "object") {
2924
				ps.loved_working = false;
2925
				ps.playcount_working = false;
2926
				b.update();
2927
				on_item_focus_change();
2928
			}
2929
			if (p.check_feature("lastfm")) {
2930
				li.artist = "";
2931
				on_item_focus_change();
2932
			}
2933
			if (p.check_feature("lastfm_album")) {
2934
				t.artist = "";
2935
				t.album = "";
2936
				on_item_focus_change();
2937
			}
2938
			window.Repaint();
2939
		}
2940
	}
2941
	
2942
	this.post = function(method, metadb) {
2943
		if (!this.xmlhttp) this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2944
		switch(method) {
2945
			case "auth.getMobileSession":
2946
				var func = function() {
2947
					var json_data = p.json_parse(l.xmlhttp.responsetext);
2948
					if (!json_data) return;
2949
					if (json_data.error) {
2950
						p.MsgBox(json_data.message, 0, p.name);
2951
					} else if (json_data.session) {
2952
						p.save(json_data.session.key, l.sk_file);
2953
						window.NotifyOthers("lastfm", "update");
2954
						l.notify_data("lastfm", "update");
2955
					}
2956
				}
2957
				
2958
				this.authToken = hex_md5(this.username + hex_md5(this.password));
2959
				this.api_sig = hex_md5("api_key" + this.api_key + "authToken" + this.authToken + "method" + method + "username" + this.username + this.secret);
2960
				this.data = "method=" + method + "&api_key=" + this.api_key + "&api_sig=" + this.api_sig + "&format=json&authToken=" + this.authToken + "&username=" + this.username;
2961
				break;
2962
			case "track.love":
2963
			case "track.unlove":
2964
				var func = function() {
2965
					var json_data = p.json_parse(l.xmlhttp.responsetext);
2966
					if (!json_data) return;
2967
					if (json_data.error) {
2968
						p.console(json_data.message);
2969
					} else if (json_data.status && json_data.status == "ok") {
2970
						p.console("Track " + (method == "track.love" ? "loved successfully." : "unloved successfully."));
2971
						fb.RunContextCommandWithMetadb("Customdb Love " + (method == "track.love" ? 1 : 0), metadb, 8);
2972
					}
2973
				}
2974
				
2975
				if (!metadb || this.username.length == 0 || this.sk.length != 32) return;
2976
				this.artist = fb.TitleFormat(p.artist_tf).EvalWithMetadb(metadb);
2977
				this.track = fb.TitleFormat("%title%").EvalWithMetadb(metadb);
2978
				if (this.artist == "" || this.artist == "?" || this.track == "?") return;
2979
				p.console("Attempting to " + (method == "track.love" ? "love \"" : "unlove \"") + this.track + "\" by \"" + this.artist + "\"");
2980
				p.console("Contacting Last.fm....");
2981
				this.api_sig = hex_md5("api_key" + this.api_key + "artist" + this.artist + "method" + method + "sk" + this.sk + "track" + this.track + this.secret);
2982
				this.data = "method=" + method + "&api_key=" + this.api_key + "&api_sig=" + this.api_sig + "&format=json&sk=" + this.sk + "&artist=" + encodeURIComponent(this.artist) + "&track=" + encodeURIComponent(this.track);
2983
				break;
2984
			default:
2985
				return;
2986
		}
2987
		
2988
		this.xmlhttp.open("POST", "https://ws.audioscrobbler.com/2.0/", true);
2989
		this.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
2990
		this.xmlhttp.setRequestHeader("User-Agent", this.user_agent);
2991
		this.xmlhttp.send(this.data);
2992
		this.xmlhttp.onreadystatechange = function() {
2993
			if (l.xmlhttp.readyState == 4) {
2994
				if (l.xmlhttp.status == 200) {
2995
					func();
2996
				} else {
2997
					p.console(l.xmlhttp.responsetext || "HTTP error: " + l.xmlhttp.status);
2998
				}
2999
			}
3000
		}
3001
	}
3002
	
3003
	this.update_username = function() {
3004
		var old_username = this.username;
3005
		this.username = p.InputBox("Enter your Last.fm username.", p.name, this.username);
3006
		if (this.username.length > 0 && this.username != old_username) p.save("", this.sk_file);
3007
		p.save(this.username, this.username_file);
3008
		window.NotifyOthers("lastfm", "update");
3009
		this.notify_data("lastfm", "update");
3010
	}
3011
	
3012
	this.update_password = function() {
3013
		this.password = p.InputBox("Enter your Last.fm password\n\nThis is only required to love/unlove tracks.", p.name, "");
3014
		if (this.password.length > 0) {
3015
			this.sk = "";
3016
			p.save(this.sk, this.sk_file);
3017
			window.NotifyOthers("lastfm", "update");
3018
			this.notify_data("lastfm", "update");
3019
			this.post("auth.getMobileSession");
3020
		}
3021
	}
3022
	
3023
	this.get_url = function() {
3024
		return "http://ws.audioscrobbler.com/2.0/?format=json&api_key=" + this.api_key + "&user=" + this.username + "&username=" + this.username + "&s=" + Math.random();
3025
	}
3026
	
3027
	this.username_error = "Use the right click menu to set your Last.fm username.";
3028
	this.password_error = "Use the right click menu to set your Last.fm password.";
3029
	this.url = "http://www.last.fm/";
3030
	this.api_key = "56d9e050cc2d6b36102c8b4a5fe6152d";
3031
	this.secret = "9f1f4346ce3ba206390074ff8cb4c6ce";
3032
	this.user_agent = "foobar2000_wsh_panel_mod_scripts";
3033
	this.username_file = p.settings_folder + "username";
3034
	this.username = p.open(this.username_file).trim();
3035
	this.sk_file = p.settings_folder + "sk";
3036
	this.sk = p.open(this.sk_file).trim();
3037
	this.auto_correct = window.GetProperty("lastfm_auto_correct", true);
3038
}
3039
3040
function list(x, y, w, h) {
3041
	this.size = function() {
3042
		this.row_height = this.mode == "echonest" ? 90 : 20;
3043
		this.rows = Math.floor((this.h - (this.mode == "echonest" ? 50 : 30)) / this.row_height);
3044
		this.index = 0;
3045
		this.offset = 0;
3046
		switch(true) {
3047
			case this.mode == "lastfm_charts":
3048
				this.text_width = Math.round(this.w / 3);
3049
				this.lastfm_charts_bar_x = this.text_width + 30;
3050
				break;
3051
			case this.mode == "musicbrainz" && this.musicbrainz_mode == "releases":
3052
				this.text_width = this.w - 120;
3053
				break;
3054
			default:
3055
				this.text_width = this.w - 50;
3056
				break;
3057
		}
3058
		this.but_x = this.x + Math.round((this.w - 15) / 2);
3059
		this.up_btn = new sb(this.but_x, this.y, 15, 15, p.up_img, "li.offset > 0", function() { li.wheel(1); });
3060
		this.down_btn = new sb(this.but_x, this.y + this.h - 15, 15, 15, p.down_img, "li.offset < li.items - li.rows", function() { li.wheel(-1); });
3061
	}
3062
	
3063
	this.draw = function(gr) {
3064
		switch(this.mode) {
3065
			case "discogs":
3066
				for (i = 0; i < Math.min(this.items, this.rows); i++) {
3067
					p.left_text(gr, this.names[i + this.offset], p.list_font, p.textcolour, this.x + this.text_x, this.y + 15 + (i * this.row_height), this.text_width, 20);
3068
					p.right_text(gr, this.dates[i + this.offset], p.list_font, p.textcolour_hl, this.x, this.y + 15 + (i * this.row_height), this.w, 20);
3069
				}
3070
				break;
3071
			case "lastfm_charts":
3072
				var max_bar_width = (this.w - this.lastfm_charts_bar_x - 40) / this.playcounts[0];
3073
				for (i = 0; i < Math.min(this.items, this.rows); i++) {
3074
					p.right_text(gr, this.ranks[i + this.offset] + ".", p.list_font, p.textcolour_hl, this.x, this.y + 15 + (i * this.row_height), 17, 20);
3075
					var bar_width = max_bar_width * this.playcounts[i + this.offset];
3076
					var bar_colour = p.splitRGB(this.lastfm_charts_bar_colour);
3077
					gr.FillSolidRect(this.lastfm_charts_bar_x + this.x, this.y + 16 + (i * this.row_height), bar_width, 18, bar_colour);
3078
					p.left_text(gr, this.playcounts[i + this.offset].addCommas(), p.list_font, p.textcolour, this.x + 5 + this.lastfm_charts_bar_x + bar_width, this.y + 15 + (i * this.row_height), 50, 20);
3079
					p.left_text(gr, this.names[i + this.offset], p.list_font, p.textcolour, this.x + this.text_x, this.y + 15 + (i * this.row_height), this.text_width, 20);
3080
				}
3081
				break;
3082
			case "lastfm":
3083
				for (i = 0; i < Math.min(this.items, this.rows); i++) {
3084
					if (this.lastfm_mode == 0) p.draw_image(gr, this.lastfm_button == "spotify" ? this.lastfm_spotify_img : this.autoplaylist_img, this.x, this.y + 16 + (i * this.row_height), 16, 16, "adjust");
3085
					if (this.lastfm_mode == 1 || this.lastfm_mode == 3 || this.lastfm_mode == 4) p.draw_image(gr, this.autoplaylist_img, this.x, this.y + 16 + (i * this.row_height), 16, 16, "adjust");
3086
					p.left_text(gr, this.names[i + this.offset], p.list_font, p.textcolour, this.x + this.text_x, this.y + 15 + (i * this.row_height), this.text_width, 20);
3087
				}
3088
				break;
3089
			case "musicbrainz":
3090
				for (i = 0; i < Math.min(this.items, this.rows); i++) {
3091
					if (this.musicbrainz_mode == "URLs") p.draw_image(gr, this.musicbrainz_images[this.images[i + this.offset]], this.x, this.y + 16 + (i * this.row_height), 16, 16, "adjust");
3092
					if (this.musicbrainz_mode == "releases") {
3093
						p.draw_image(gr, this.autoplaylist_img, this.x, this.y + 16 + (i * this.row_height), 16, 16, "adjust");
3094
						if (this.musicbrainz_show_release_type) p.right_text(gr, this.release_types[i + this.offset], p.list_font, p.textcolour, this.x, this.y + 15 + (i * this.row_height), this.w - 30, 20);
3095
						p.right_text(gr, this.dates[i + this.offset], p.list_font, p.textcolour_hl, this.x, this.y + 15 + (i * this.row_height), this.w, 20);
3096
					}
3097
					p.left_text(gr, this.names[i + this.offset], p.list_font, p.textcolour, this.x + this.text_x, this.y + 15 + (i * this.row_height), this.text_width, 20);
3098
				}
3099
				break;
3100
			case "autoplaylists":
3101
				for (i = 0; i < Math.min(this.items, this.rows); i++) {
3102
					p.left_text(gr, this.names[i + this.offset], p.list_font, p.textcolour, this.x, this.y + 15 + (i * this.row_height), this.text_width, 20);
3103
					if (!this.autoplaylists_editing && this.autoplaylists_hover && this.index == i + this.offset) {
3104
						p.draw_image(gr, this.autoplaylists_edit_img, this.x + this.w - 40, this.y + 16 + (i * this.row_height), 16, 16, "adjust");
3105
						p.draw_image(gr, this.autoplaylists_del_img, this.x + this.w - 20, this.y + 16 + (i * this.row_height), 16, 16, "adjust");
3106
					}
3107
				}
3108
				break;
3109
			case "echonest":
3110
				for (i = 0; i < Math.min(this.items, this.rows); i++) {
3111
					p.left_text(gr, this.names[i + this.offset], p.title_font, p.textcolour_hl, this.x, this.y + 15 + (i * this.row_height), this.w - 110, 24);
3112
					p.right_text(gr, this.dates[i + this.offset], p.title_font, p.textcolour_hl, this.x, this.y + 15 + (i * this.row_height), this.w, 24);
3113
					gr.GdiDrawText(this.summaries[i + this.offset], p.normal_font, p.textcolour, this.x, this.y + 37 + (i * this.row_height), this.w, p.normal_font.Height * Math.floor(64 / p.normal_font.Height), DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
3114
				}
3115
				break;
3116
		}
3117
		this.up_btn.draw(gr);
3118
		this.down_btn.draw(gr);
3119
		if (this.show_timestamp) p.left_text(gr, this.date, p.list_font, p.textcolour_hl, this.x, this.y + this.h - 15, this.w, 15);
3120
	}
3121
	
3122
	this.metadb_changed = function() {
3123
		p.artist = p.eval(p.artist_tf);
3124
		if (this.artist == p.artist) return false;
3125
		this.artist = p.artist;
3126
		this.folder = p.data_folder + p.artist_tf;
3127
		//if (!p.fso.FolderExists(this.folder)) p.fso.CreateFolder(this.folder);
3128
		this.update();
3129
		return true;
3130
	}
3131
	
3132
	this.trace = function(x, y) {
3133
		return (x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h);
3134
	}
3135
	
3136
	this.wheel = function(step) {
3137
		if (!this.trace(p.mx, p.my)) return false;
3138
		if (this.items > this.rows) {
3139
			this.offset -= step * (this.mode == "echonest" ? 1 : 3);
3140
			if (this.offset < 0) this.offset = 0;
3141
			if (this.rows + this.offset > this.items) this.offset = this.items - this.rows;
3142
			window.RepaintRect(this.x, this.y, this.w, this.h);
3143
		}
3144
		return true;
3145
	}
3146
	
3147
	this.move = function(x, y) {
3148
		this.index = Math.floor((y - this.y - 15) / this.row_height) + this.offset;
3149
		this.in_range = this.index >= this.offset && this.index < this.offset + Math.min(this.rows, this.items);
3150
		switch(true) {
3151
			case !this.trace(x, y):
3152
			case this.mode == "autoplaylists" && this.autoplaylists_editing:
3153
			case this.mode == "lastfm" && l.username.length == 0:
3154
				window.SetCursor(IDC_ARROW);
3155
				this.leave();
3156
				return false;
3157
			case this.up_btn.trace(x, y):
3158
			case this.down_btn.trace(x, y):
3159
				window.SetCursor(IDC_HAND);
3160
				break;
3161
			case !this.in_range:
3162
				window.SetCursor(IDC_ARROW);
3163
				this.leave();
3164
				break;
3165
			case this.mode == "musicbrainz" && this.musicbrainz_mode == "releases" && x > this.x && x < this.x + 20:
3166
			case this.mode == "lastfm" && this.text_x == 20 && x > this.x && x < this.x + 20:
3167
				window.SetCursor(IDC_HAND);
3168
				switch(true) {
3169
					case this.lastfm_mode == 0 && this.lastfm_button == "spotify":
3170
						p.tt('spotify:search:"' + this.names[this.index].replace(/\s+/g, "+") + '"');
3171
						break;
3172
					default:
3173
						p.tt("Autoplaylist: " + this.queries[this.index]);
3174
						break;
3175
				}
3176
				break;
3177
			case this.mode == "autoplaylists":
3178
				switch(true) {
3179
					case x > this.x && x < this.x + Math.min(this.names_widths[this.index], this.text_width):
3180
						window.SetCursor(IDC_HAND);
3181
						p.tt('Run "' + this.names[this.index] + '"');
3182
						break;
3183
					case x > this.x + this.w - 40 && x < this.x + this.w - 20:
3184
						window.SetCursor(IDC_HAND);
3185
						p.tt('Edit "' + this.names[this.index] + '"');
3186
						break;
3187
					case x > this.x + this.w - 20 && x < this.x + this.w:
3188
						window.SetCursor(IDC_HAND);
3189
						p.tt('Delete "' + this.names[this.index] + '"');
3190
						break;
3191
					default:
3192
						window.SetCursor(IDC_ARROW);
3193
						this.leave();
3194
						break;
3195
				}
3196
				this.autoplaylists_hover = true;
3197
				window.RepaintRect(this.x + this.w - 40, this.y + 15, 40, Math.min(this.rows, this.items) * this.row_height);
3198
				break;
3199
			case this.mode == "echonest":
3200
			case x > this.x + this.text_x && x < this.x + this.text_x + Math.min(this.names_widths[this.index], this.text_width):
3201
				window.SetCursor(IDC_HAND);
3202
				p.tt(this.urls[this.index]);
3203
				break;
3204
			default:
3205
				window.SetCursor(IDC_ARROW);
3206
				p.ttd();
3207
				break;
3208
		}
3209
		return true;
3210
	}
3211
	
3212
	this.lbtn_up = function(x, y) {
3213
		switch(true) {
3214
			case !this.trace(x, y):
3215
				return false;
3216
			case this.mode == "autoplaylists" && this.autoplaylists_editing:
3217
			case this.mode == "lastfm" && l.username.length == 0:
3218
			case this.up_btn.lbtn_up(x, y):
3219
			case this.down_btn.lbtn_up(x, y):
3220
			case !this.in_range:
3221
				break;
3222
			case this.mode == "musicbrainz" && this.musicbrainz_mode == "releases" && x > this.x && x < this.x + 20:
3223
			case this.mode == "lastfm" && this.text_x == 20 && x > this.x && x < this.x + 20:
3224
				switch(true) {
3225
					case this.lastfm_mode == 0 && this.lastfm_button == "spotify":
3226
						if (p.run('spotify:search:"' + this.names[this.index].replace(/\s+/g, "+") + '"')) {
3227
							if (fb.IsPlaying && !fb.IsPaused && this.lastfm_pause) fb.Pause();
3228
						} else {
3229
							p.MsgBox("Unable to launch Spotify.", 0, p.name);
3230
						}
3231
						break;
3232
					default:
3233
						fb.CreateAutoPlaylist(fb.PlaylistCount, this.names[this.index], this.queries[this.index]);
3234
						fb.ActivePlaylist = fb.PlaylistCount - 1;
3235
						break;
3236
				}
3237
				break;
3238
			case this.mode == "autoplaylists":
3239
				switch(true) {
3240
					case x > this.x && x < this.x + Math.min(this.names_widths[this.index], this.text_width):
3241
						this.autoplaylists_run(this.names[this.index], this.queries[this.index], this.sorts[this.index], this.forced[this.index]);
3242
						break;
3243
					case x > this.x + this.w - 40 && x < this.x + this.w - 20:
3244
						this.autoplaylists_edit(x, y);
3245
						break;
3246
					case x > this.x + this.w - 20 && x < this.x + this.w:
3247
						this.autoplaylists_delete();
3248
						break
3249
				}
3250
				break;
3251
			case this.mode == "echonest":
3252
			case x > this.x + this.text_x && x < this.x + this.text_x + Math.min(this.names_widths[this.index], this.text_width):
3253
				p.browser(this.urls[this.index]);
3254
				break;
3255
		}
3256
		return true;
3257
	}
3258
	
3259
	this.leave = function() {
3260
		p.ttd();
3261
		if (this.mode != "autoplaylists") return;
3262
		this.autoplaylists_hover = false;
3263
		window.RepaintRect(this.x, this.y, this.w, this.h);
3264
	}
3265
	
3266
	this.update = function() {
3267
		this.items = 0;
3268
		this.offset = 0;
3269
		this.index = 0;
3270
		this.names = [];
3271
		this.names_widths = [];
3272
		this.urls = [];
3273
		this.dates = [];
3274
		this.queries = [];
3275
		this.ranks = [];
3276
		this.playcounts = [];
3277
		this.sorts = [];
3278
		this.summaries = [];
3279
		this.release_types = [];
3280
		this.images = [];
3281
		this.forced = [];
3282
		this.data = [];
3283
		this.file = null;
3284
		this.date = "";
3285
		var temp_bmp = gdi.CreateImage(1, 1);
3286
		var temp_gr = temp_bmp.GetGraphics();
3287
		switch(this.mode) {
3288
			case "autoplaylists":
3289
				this.text = p.open(this.filename);
3290
				this.data = this.text.split(/\r?\n/g);
3291
				this.items = this.data.length;
3292
				for (i = 0; i < this.items; i++) {
3293
					var temp = this.data[i].split("¬");
3294
					this.names[i] = temp[0];
3295
					this.queries[i] = temp[1];
3296
					this.sorts[i] = temp[2];
3297
					this.forced[i] = temp[3];
3298
					this.names_widths[i] = temp_gr.CalcTextWidth(this.names[i], p.list_font);
3299
				}
3300
				break;
3301
			case "lastfm":
3302
				this.text_x = 20;
3303
				this.filename = this.folder + "\\" + this.lastfm_methods[this.lastfm_mode] + ".json";
3304
				if (p.fso.fileExists(this.filename)) {
3305
					this.file = p.fso.Getfile(this.filename);
3306
					this.json_text = p.open(this.filename);
3307
					this.json_data = p.json_parse(this.json_text);
3308
					if (this.json_data) {
3309
						switch(true) {
3310
							case this.json_data.error > 0:
3311
								p.console(this.json_data.message);
3312
								break;
3313
							case this.lastfm_mode == 0 && this.json_data.similarartists && typeof this.json_data.similarartists.artist == "object":
3314
								this.data = this.json_data.similarartists.artist;
3315
								break;
3316
							case this.lastfm_mode == 1 && this.json_data.toptags && typeof this.json_data.toptags.tag == "object":
3317
								this.data = this.json_data.toptags.tag;
3318
								break;
3319
							case this.lastfm_mode == 2 && this.json_data.topfans && typeof this.json_data.topfans.user == "object":
3320
								this.text_x = 0;
3321
								this.data = this.json_data.topfans.user;
3322
								break;
3323
							case this.lastfm_mode == 3 && this.json_data.topalbums && typeof this.json_data.topalbums.album == "object":
3324
								this.data = this.json_data.topalbums.album;
3325
								break;
3326
							case this.lastfm_mode == 4 && this.json_data.toptracks && typeof this.json_data.toptracks.track == "object":
3327
								this.data = this.json_data.toptracks.track;
3328
								break;
3329
						}
3330
						this.items = this.data.length;
3331
						for (i = 0; i < this.items; i++) {
3332
							this.names[i] = this.data[i].name;
3333
							this.urls[i] = this.data[i].url;
3334
							this.names_widths[i] = temp_gr.CalcTextWidth(this.names[i], p.list_font);
3335
							if (this.lastfm_mode == 0) this.queries[i] = "artist HAS " + this.names[i];
3336
							if (this.lastfm_mode == 1) this.queries[i] = "genre HAS " + this.names[i];
3337
							if (this.lastfm_mode == 3) this.queries[i] = "album HAS " + this.names[i] + " OR title HAS " + this.names[i];
3338
							if (this.lastfm_mode == 4) this.queries[i] = "title HAS " + this.names[i];
3339
						}
3340
					}
3341
					if (Date.parse(Date()) - Date.parse(this.file.DateLastModified) > ONE_DAY) this.get();
3342
				} else {
3343
					this.get();
3344
				}
3345
				break;
3346
			case "lastfm_charts":
3347
				this.filename = this.folder + "\\" + l.username + "_" + this.lastfm_charts_modes[this.lastfm_charts_mode] + "_" + this.lastfm_charts_periods[this.lastfm_charts_period] + ".json";
3348
				if (p.fso.fileExists(this.filename)) {
3349
					this.file = p.fso.Getfile(this.filename);
3350
					this.json_text = p.open(this.filename);
3351
					this.json_data = p.json_parse(this.json_text);
3352
					if (this.json_data) {
3353
						switch(true) {
3354
							case this.json_data.error > 0:
3355
								p.console(this.json_data.message);
3356
								break;
3357
							case this.lastfm_charts_mode == 0 && this.json_data.topartists && typeof this.json_data.topartists.artist == "object":
3358
								this.data = this.json_data.topartists.artist;
3359
								break;
3360
							case this.lastfm_charts_mode == 1 && this.json_data.topalbums && typeof this.json_data.topalbums.album == "object":
3361
								this.data = this.json_data.topalbums.album;
3362
								break;
3363
							case this.lastfm_charts_mode == 2 && this.json_data.toptracks && typeof this.json_data.toptracks.track == "object":
3364
								this.data = this.json_data.toptracks.track;
3365
								break;
3366
						}
3367
						this.items = this.data.length;
3368
						for (i = 0; i < this.items; i++) {
3369
							this.names[i] = this.lastfm_charts_mode != 0 ? this.data[i].artist.name + " - " + this.data[i].name : this.data[i].name;
3370
							this.ranks[i] = (i > 0 && this.data[i].playcount == this.data[i - 1].playcount) ? this.ranks[i - 1] : this.data[i]["@attr"].rank;
3371
							this.urls[i] = this.data[i].url;
3372
							this.names_widths[i] = temp_gr.CalcTextWidth(this.names[i], p.list_font);
3373
							this.playcounts[i] = this.data[i].playcount;
3374
						}
3375
					}
3376
					if (Date.parse(Date()) - Date.parse(this.file.DateLastModified) > ONE_DAY) this.get();
3377
				} else {
3378
					this.get();
3379
				}
3380
				break;
3381
			case "discogs":
3382
				this.filename = this.folder + "\\discogs.json";
3383
				if (p.fso.fileExists(this.filename)) {
3384
					this.file = p.fso.Getfile(this.filename);
3385
					this.json_text = p.open(this.filename);
3386
					this.json_data = p.json_parse(this.json_text);
3387
					if (this.json_data && this.json_data.results) {
3388
						this.data = this.json_reverse_sort(this.json_data.results, "year");
3389
						var swap_artist = fb.TitleFormat("$swapprefix($lower(" + p.artist + ")) - ").Eval(true);
3390
						for (i = 0; i < this.data.length; i++) {
3391
							var temp_artist = this.data[i].title.replace(/\s{2,}/g,' ');
3392
							if (this.discogs_match && temp_artist.toLowerCase().indexOf(swap_artist) != 0) continue;
3393
							this.dates.push(this.data[i].year || "");
3394
							this.urls.push("http://www.discogs.com" + this.data[i].uri);
3395
							this.names.push(temp_artist);
3396
							this.names_widths.push(temp_gr.CalcTextWidth(temp_artist, p.list_font));
3397
						}
3398
						this.items = this.names.length;
3399
					}
3400
					if (Date.parse(Date()) - Date.parse(this.file.DateLastModified) > ONE_DAY) this.get();
3401
				} else {
3402
					this.get();
3403
				}
3404
				break;
3405
			case "musicbrainz":
3406
				this.filename = this.folder + "\\musicbrainz_" + this.musicbrainz_mode + ".json";
3407
				if (p.fso.fileExists(this.filename)) {
3408
					this.file = p.fso.Getfile(this.filename);
3409
					this.json_text = p.open(this.filename);
3410
					this.json_data = p.json_parse(this.json_text);
3411
					if (this.json_data) {
3412
						switch(this.musicbrainz_mode) {
3413
							case "releases":
3414
								this.data = this.json_data["release-groups"] || [];
3415
								this.data = this.json_reverse_sort(this.data, "first-release-date");
3416
								var primary, secondary, name;
3417
								for (i = 0; i < this.data.length; i++) {
3418
									primary = this.data[i]["primary-type"];
3419
									secondary = this.data[i]["secondary-types"].join("").toLowerCase();
3420
									switch(true) {
3421
										case !this.musicbrainz_remix && secondary.indexOf("remix") > -1:
3422
										case !this.musicbrainz_compilation && secondary.indexOf("compilation") > -1:
3423
										case !this.musicbrainz_live && secondary.indexOf("live") > -1:
3424
											break;
3425
										case this.musicbrainz_single && primary == "Single":
3426
										case this.musicbrainz_ep && primary == "EP":
3427
										case this.musicbrainz_album && primary == "Album":
3428
											name = this.data[i].title;
3429
											this.dates.push(this.data[i]["first-release-date"].substring(0,4));
3430
											this.names.push(name);
3431
											this.urls.push("http://musicbrainz.org/release-group/" + this.data[i].id);
3432
											this.names_widths.push(temp_gr.CalcTextWidth(name, p.list_font));
3433
											this.queries.push("album HAS " + name + " OR title HAS " + name);
3434
											switch(true) {
3435
												case secondary.indexOf("remix") > -1:
3436
													this.release_types.push("Remix");
3437
													break;
3438
												case secondary.indexOf("compilation") > -1:
3439
													this.release_types.push("Compilation");
3440
													break;
3441
												case secondary.indexOf("live") > -1:
3442
													this.release_types.push("Live");
3443
													break;
3444
												default:
3445
													this.release_types.push(primary);
3446
													break;
3447
											}
3448
									}
3449
								}
3450
								this.items = this.names.length;
3451
								break;
3452
							case "URLs":
3453
								this.data = this.json_data.relations || [];
3454
								this.items = this.data.length;
3455
								for (i = 0; i < this.items; i++) {
3456
									this.urls[i] = this.data[i].url.resource;
3457
									this.images[i] = "";
3458
									if (this.data[i].type == "official homepage") {
3459
										this.images[i] = "home";
3460
									} else {
3461
										for (name in this.musicbrainz_images) {
3462
											if (this.urls[i].indexOf(name) > -1) {
3463
												this.images[i] = name;
3464
												break;
3465
											}
3466
										}
3467
										if (this.images[i].length == 0) this.images[i] = "external";
3468
									}
3469
									this.names[i] = decodeURIComponent(this.urls[i]);
3470
									this.names_widths[i] = temp_gr.CalcTextWidth(this.names[i], p.list_font);
3471
								}
3472
								break;
3473
						}
3474
					}
3475
					if (Date.parse(Date()) - Date.parse(this.file.DateLastModified) > ONE_DAY) this.get();
3476
				} else {
3477
					this.get();
3478
				}
3479
				break;
3480
			case "echonest":
3481
				this.filename = this.folder + "\\echonest_" + this.echonest_modes[this.echonest_mode] + ".json";
3482
				if (p.fso.fileExists(this.filename)) {
3483
					this.file = p.fso.Getfile(this.filename);
3484
					this.json_text = p.open(this.filename);
3485
					this.json_data = p.json_parse(this.json_text);
3486
					if (this.json_data && this.json_data.response && this.json_data.response.status && this.json_data.response.status.code == 0) {
3487
						this.data = this.json_data.response[this.echonest_modes[this.echonest_mode]] || [];
3488
						this.items = this.data.length;
3489
						for (i = 0; i < this.items; i++) {
3490
							this.names[i] = p.strip_tags(this.data[i].name);
3491
							this.urls[i] = (this.data[i].url || "").replace(/\\/g, "");
3492
							this.temp_date = (this.data[i].date_posted || this.data[i].date_reviewed || this.data[i].date_found || "").substring(0, 10);
3493
							this.dates[i] = this.temp_date.substring(8,10) + "-" + this.temp_date.substring(5,7) + "-" + this.temp_date.substring(0,4);
3494
							this.summaries[i] = p.strip_tags(this.data[i].summary);
3495
						}
3496
					}
3497
					if (Date.parse(Date()) - Date.parse(this.file.DateLastModified) > ONE_DAY) this.get();
3498
				} else {
3499
					this.get();
3500
				}
3501
				break;
3502
		}
3503
		temp_bmp.ReleaseGraphics(temp_gr);
3504
		temp_bmp.Dispose();
3505
		temp_gr = null;
3506
		temp_bmp = null;
3507
		if (this.file) {
3508
			var temp_date = new Date(this.file.DateLastModified);
3509
			this.date = "Updated: " + temp_date.toLocaleTimeString() + ", " + temp_date.toLocaleDateString();
3510
		}
3511
		window.Repaint();
3512
	}
3513
	
3514
	this.get = function() {
3515
		var fn = this.filename;
3516
		var func = function() {
3517
			if (!p.save(li.xmlhttp.responsetext, fn)) return;
3518
			li.update();
3519
		}
3520
		var url = "";
3521
		var user_agent = "";
3522
		switch(this.mode) {
3523
			case "discogs":
3524
				if (this.artist == "" || this.artist == "?") return;
3525
				url = "http://api.discogs.com/database/search?per_page=100&type=master&artist=" + encodeURIComponent(this.artist);
3526
				user_agent = "foobar2000_wsh_panel_mod_discogs +http://www.hydrogenaudio.org/forums/index.php?showuser=19379";
3527
				break;
3528
			case "lastfm_charts":
3529
				if (l.username.length == 0) return(p.console(l.username_error));
3530
				url = l.get_url() + "&method=user." + this.lastfm_charts_methods[this.lastfm_charts_mode] + "&period=" + this.lastfm_charts_periods[this.lastfm_charts_period];
3531
				user_agent = l.user_agent;
3532
				break;
3533
			case "lastfm":
3534
				if (this.artist == "" || this.artist == "?") return;
3535
				if (l.username.length == 0) return(p.console(l.username_error));
3536
				url = l.get_url() + "&method=" + this.lastfm_methods[this.lastfm_mode] + "&artist=" + encodeURIComponent(this.artist) + "&autocorrect=" + (l.auto_correct ? 1 : 0);
3537
				user_agent = l.user_agent;
3538
				break;
3539
			case "musicbrainz":
3540
				user_agent = "foobar2000_wsh_panel_mod_musicbrainz +http://www.hydrogenaudio.org/forums/index.php?showuser=19379";
3541
				var fn1 = this.folder + "\\MUSICBRAINZ_ARTISTID.txt";
3542
				this.musicbrainz_id = p.eval("$if3(%musicbrainz_artistid%,%musicbrainz artist id%,)");
3543
				this.musicbrainz_id = this.musicbrainz_id.substring(0, 36);
3544
				if (this.musicbrainz_id.length == 0) this.musicbrainz_id = p.open(fn1);
3545
				if (this.musicbrainz_id.length == 0) {
3546
					if (this.artist == "" || this.artist == "?") return;
3547
					url = "https://musicbrainz.org/ws/2/artist/?query=artist:" + encodeURIComponent(this.artist.toLowerCase()) + "&fmt=json";
3548
					var func = function() {
3549
						var json_data = p.json_parse(li.xmlhttp.responsetext);
3550
						if (!json_data) return;
3551
						var artist = li.artist.toLowerCase();
3552
						var artists = json_data.artist || [];
3553
						for (i = 0; i < artists.length; i++) {
3554
							if (artist == artists[i].name.toLowerCase()) {
3555
								if (!p.save(artists[i].id, fn1)) return;
3556
								li.get();
3557
								break;
3558
							}
3559
						}
3560
					}
3561
				} else {
3562
					if (this.musicbrainz_mode == "releases") url = "https://musicbrainz.org/ws/2/release-group?artist=" + this.musicbrainz_id + "&limit=100&offset=0&fmt=json";
3563
					else url = "https://musicbrainz.org/ws/2/artist/" + this.musicbrainz_id + "?inc=url-rels&fmt=json";
3564
				}
3565
				break;
3566
			case "echonest":
3567
				if (this.artist == "" || this.artist == "?") return;
3568
				url = "http://developer.echonest.com/api/v4/artist/" + this.echonest_modes[this.echonest_mode] + "/?name=" + encodeURIComponent(this.artist) + "&api_key=EKWS4ESQLKN3G2ZWV";
3569
				break;
3570
		}
3571
		if (url.length == 0) return;
3572
		this.xmlhttp.open("GET", url, true);
3573
		if (user_agent.length > 0) this.xmlhttp.setRequestHeader('User-Agent', user_agent);
3574
		this.xmlhttp.send();
3575
		this.xmlhttp.onreadystatechange = function() {
3576
			if (li.xmlhttp.readyState == 4) {
3577
				if (li.xmlhttp.status == 200) {
3578
					func();
3579
				} else {
3580
					p.console(li.xmlhttp.responsetext || "HTTP error: " + li.xmlhttp.status);
3581
				}
3582
			}
3583
		}
3584
	}
3585
	
3586
	this.json_reverse_sort = function(data, prop) {
3587
		data = data.sort(function(a, b) {
3588
			if (!a[prop] || b[prop] > a[prop]) return 1;
3589
			if (!b[prop] || b[prop] < a[prop]) return -1;
3590
			return 0;
3591
		});
3592
		return data;
3593
	}
3594
	
3595
	this.init = function() {
3596
		switch(true) {
3597
			case p.check_feature("discogs"):
3598
				this.mode = "discogs";
3599
				this.discogs_match = window.GetProperty("discogs_match", false);
3600
				break;
3601
			case p.check_feature("lastfm_charts"):
3602
				this.mode = "lastfm_charts";
3603
				this.text_x = 20;
3604
				this.lastfm_charts_modes = ["artist", "album", "track"];
3605
				this.lastfm_charts_mode = window.GetProperty("lastfm_charts_mode", 0);
3606
				this.lastfm_charts_methods = ["getTopArtists", "getTopAlbums", "getTopTracks"];
3607
				this.lastfm_charts_periods_display = ["overall", "last 7 days", "1 month", "3 month", "6 month", "12 month"];
3608
				this.lastfm_charts_periods = ["overall", "7day", "1month", "3month", "6month", "12month"];
3609
				this.lastfm_charts_period = window.GetProperty("lastfm_charts_period", 0);
3610
				this.lastfm_charts_bar_colour = window.GetProperty("lastfm_charts_bar_colour", "72-127-221");
3611
				this.folder = p.data_folder + "charts";
3612
				//if (!p.fso.FolderExists(this.folder)) p.fso.CreateFolder(this.folder);
3613
				break;
3614
			case p.check_feature("lastfm"):
3615
				this.mode = "lastfm";
3616
				this.lastfm_methods = ["artist.getSimilar", "artist.getTopTags", "artist.getTopFans", "artist.getTopAlbums", "artist.getTopTracks"];
3617
				this.lastfm_modes = ["similar artists", "top tags", "top fans", "top albums", "top tracks"];
3618
				this.lastfm_mode = window.GetProperty("lastfm_mode", 0);
3619
				this.lastfm_button = window.GetProperty("lastfm_button", "spotify");
3620
				this.lastfm_pause = window.GetProperty("lastfm_pause", true);
3621
				this.lastfm_spotify_img = gdi.Image(p.images_path + "spotify.png");
3622
				break;
3623
			case p.check_feature("musicbrainz"):
3624
				this.mode = "musicbrainz";
3625
				this.text_x = 20;
3626
				this.musicbrainz_images = {
3627
					"viaf.org": gdi.Image(p.images_path + "viaf_small.png"),
3628
					"allmusic.com": gdi.Image(p.images_path + "allmusic_small.png"),
3629
					"external": gdi.Image(p.images_path + "external_small.png"),
3630
					"bbc.co.uk": gdi.Image(p.images_path + "bbc_small.png"),
3631
					"facebook.com": gdi.Image(p.images_path + "facebook_small.png"),
3632
					"home": gdi.Image(p.images_path + "home_small.png"),
3633
					"last.fm": gdi.Image(p.images_path + "lastfm_small.png"),
3634
					"twitter.com": gdi.Image(p.images_path + "twitter_small.png"),
3635
					"soundcloud.com": gdi.Image(p.images_path + "soundcloud_small.png"),
3636
					"wikipedia.org": gdi.Image(p.images_path + "wikipedia_small.png"),
3637
					"discogs.com": gdi.Image(p.images_path + "discogs_small.png"),
3638
					"myspace.com": gdi.Image(p.images_path + "myspace_small.png"),
3639
					"youtube.com": gdi.Image(p.images_path + "youtube_small.png"),
3640
					"imdb.com": gdi.Image(p.images_path + "imdb_small.png"),
3641
					"plus.google.com": gdi.Image(p.images_path + "google_plus_small.png"),
3642
					"lyrics.wikia.com": gdi.Image(p.images_path + "lyrics_wikia_small.png"),
3643
					"flickr.com": gdi.Image(p.images_path + "flickr_small.png"),
3644
					"secondhandsongs.com": gdi.Image(p.images_path + "secondhandsongs_small.png"),
3645
					"vimeo.com": gdi.Image(p.images_path + "vimeo_small.png"),
3646
					"rateyourmusic.com": gdi.Image(p.images_path + "rateyourmusic_small.png"),
3647
					"instagram.com": gdi.Image(p.images_path + "instagram_small.png"),
3648
					"tumblr.com": gdi.Image(p.images_path + "tumblr_small.png"),
3649
					"decoda.com": gdi.Image(p.images_path + "decoda_small.png"),
3650
					"wikidata.org": gdi.Image(p.images_path + "wikidata_small.png")
3651
				}
3652
				this.musicbrainz_mode = window.GetProperty("musicbrainz_mode", "releases");
3653
				this.musicbrainz_show_release_type = window.GetProperty("musicbrainz_show_release_type", true);
3654
				this.musicbrainz_live = window.GetProperty("musicbrainz_live", false);
3655
				this.musicbrainz_ep = window.GetProperty("musicbrainz_ep", true);
3656
				this.musicbrainz_single = window.GetProperty("musicbrainz_single", true);
3657
				this.musicbrainz_album = window.GetProperty("musicbrainz_album", true);
3658
				this.musicbrainz_remix = window.GetProperty("musicbrainz_remix", true);
3659
				this.musicbrainz_compilation = window.GetProperty("musicbrainz_compilation", true);
3660
				break;
3661
			case p.check_feature("echonest"):
3662
				this.mode = "echonest";
3663
				this.echonest_modes = ["news", "reviews", "blogs"];
3664
				this.echonest_mode = window.GetProperty("echonest_mode", 0);
3665
				break;
3666
			case p.check_feature("autoplaylists"):
3667
				this.autoplaylists_add = function() {
3668
					if (this.autoplaylists_editing) return;
3669
					this.autoplaylists_editing = true;
3670
					var new_name = p.InputBox("Enter a name for your autoplaylist", p.name, "");
3671
					if (new_name == "") { this.autoplaylists_editing = false; return; }
3672
					var new_query = p.InputBox("Enter your autoplaylist query", p.name, "");
3673
					if (new_query == "") { this.autoplaylists_editing = false; return; }
3674
					var new_sort = p.InputBox("Enter a sort pattern\n\n(optional)", p.name, "");
3675
					var new_force = new_sort.length > 0 ? p.MsgBox("Force sort?", 4, p.name) : 7;
3676
					this.data.push(new_name + "¬" + new_query + "¬" + new_sort + "¬" + new_force);
3677
					if (this.data.length > this.rows) this.offset = this.data.length - this.rows;
3678
					p.save(this.data.join("\n"), this.filename);
3679
					if (this.autoplaylists_success) this.autoplaylists_run(new_name, new_query, new_sort, new_force);
3680
					window.NotifyOthers("autoplaylists", "update");
3681
					this.update();
3682
					this.autoplaylists_editing = false;
3683
				}
3684
				
3685
				this.autoplaylists_run = function(n, q, s, f) {
3686
					if (this.autoplaylists_remove_duplicates) {
3687
						i = 0;
3688
						while(i < fb.PlaylistCount) {
3689
							if (fb.GetPlaylistName(i) == n) fb.RemovePlaylist(i);
3690
							else i++;
3691
						}
3692
					}
3693
					fb.CreateAutoPlaylist(fb.PlaylistCount, n, q, s, f == 6 ? true : false);
3694
					fb.ActivePlaylist = fb.PlaylistCount - 1;
3695
				}
3696
				
3697
				this.autoplaylists_edit = function(x, y) {
3698
					var _menu = window.CreatePopupMenu();
3699
					var i = this.index;
3700
					_menu.AppendMenuItem(MF_STRING, 1, "Rename...");
3701
					_menu.AppendMenuItem(MF_STRING, 2, "Edit query...");
3702
					_menu.AppendMenuItem(MF_STRING, 3, "Edit sort pattern...");
3703
					_menu.AppendMenuItem(MF_STRING, 4, "Force Sort");
3704
					_menu.CheckMenuItem(4, this.forced[i] == 6 ? true : false);
3705
					this.autoplaylists_editing = true;
3706
					this.autoplaylists_hover = false;
3707
					window.RepaintRect(this.x + this.w - 40, this.y + 15, 40, Math.min(this.rows, this.items) * this.row_height);
3708
					idx = _menu.TrackPopupMenu(x, y);
3709
					switch(idx) {
3710
						case 0:
3711
							this.autoplaylists_editing = false;
3712
							_menu.Dispose();
3713
							return;
3714
						case 1:
3715
							var new_name = p.InputBox("Rename your autoplaylist", p.name, this.names[i]);
3716
							if (new_name != "") this.names[i] = new_name;
3717
							break;
3718
						case 2:
3719
							var new_query = p.InputBox("Enter your autoplaylist query", p.name, this.queries[i]);
3720
							if (new_query != "") this.queries[i] = new_query;
3721
							break;
3722
						case 3:
3723
							var new_sort = p.InputBox("Enter a sort pattern\n\n(optional)", p.name, this.sorts[i]);
3724
							this.sorts[i] = new_sort;
3725
							this.forced[i] = new_sort.length > 0 ? p.MsgBox("Force sort?", 4, p.name) : 7;
3726
							break;
3727
						case 4:
3728
							this.forced[i] = this.forced[i] == 6 ? 7 : 6;
3729
							break;
3730
					}
3731
					_menu.Dispose();
3732
					var temp = this.names[i] + "¬" + this.queries[i] + "¬" + this.sorts[i] + "¬" + this.forced[i];
3733
					if (this.data[i] != temp) {
3734
						this.data[i] = temp;
3735
						p.save(this.data.join("\n"), this.filename);
3736
						if (this.autoplaylists_success) this.autoplaylists_run(this.names[i], this.queries[i], this.sorts[i], this.forced[i]);
3737
						window.NotifyOthers("autoplaylists", "update");
3738
						this.update();
3739
					}
3740
					this.autoplaylists_editing = false;
3741
				}
3742
				
3743
				this.autoplaylists_delete = function() {
3744
					if (this.offset > 1) this.offset--;
3745
					this.autoplaylists_deleted_items.unshift(this.data[this.index]);
3746
					this.data.splice(this.index, 1);
3747
					p.save(this.data.join("\n"), this.filename);
3748
					window.NotifyOthers("autoplaylists", "update");
3749
					this.update();
3750
				}
3751
				
3752
				this.mode = "autoplaylists";
3753
				this.autoplaylists_del_img = gdi.Image(p.images_path + "cross.png");
3754
				this.autoplaylists_edit_img = gdi.Image(p.images_path + "edit.png");
3755
				this.autoplaylists_hover = false;
3756
				this.autoplaylists_editing = false;
3757
				this.autoplaylists_remove_duplicates = window.GetProperty("autoplaylists_remove_duplicates", true);
3758
				this.autoplaylists_success = window.GetProperty("autoplaylists_success", true);
3759
				this.autoplaylists_title = window.GetProperty("autoplaylists_title", "Autoplaylists");
3760
				this.autoplaylists_slot = window.GetProperty("autoplaylists_slot", 1);
3761
				this.filename = p.settings_folder + "autoplaylists" + this.autoplaylists_slot;
3762
				this.autoplaylists_deleted_items = [];
3763
				break;
3764
		}
3765
	}
3766
	
3767
	this.x = x;
3768
	this.y = y;
3769
	this.w = w;
3770
	this.h = h;
3771
	this.index = 0;
3772
	this.offset = 0;
3773
	this.items = 0;
3774
	this.text = "";
3775
	this.artist = "";
3776
	this.url = "";
3777
	this.text_x = 0;
3778
	this.show_timestamp = window.GetProperty("show_timestamp", true);
3779
	this.autoplaylist_img = gdi.Image(p.images_path + "search_small.png");
3780
	this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
3781
	this.init();
3782
}
3783
3784
function playcount_sync(x, y) {
3785
	this.playback_time = function() {
3786
		this.time_elapsed++;
3787
		if (this.time_elapsed == 3 && this.auto_love && fb.TitleFormat(this.auto_love_tf).Eval() == 1 && this.old_userloved == 0) {
3788
			p.console("Automatically loving this track....");
3789
			this.love_track();
3790
		}
3791
		if (this.time_elapsed == this.target_time) {
3792
			if (!this.library || fb.IsMetadbInMediaLibrary(p.metadb)) this.sync_track();
3793
			else p.console("Skipping... Track not in library.");
3794
		}
3795
	}
3796
	
3797
	this.metadb_changed = function() {
3798
		if (!p.metadb) return false;
3799
		this.artist = fb.TitleFormat(p.artist_tf).EvalWithMetadb(p.metadb);
3800
		this.track = fb.TitleFormat("%title%").EvalWithMetadb(p.metadb);
3801
		this.old_userloved = fb.TitleFormat("%LASTFM_LOVED_DB%").EvalWithMetadb(p.metadb) == 1 ? 1 : 0;
3802
		this.old_userplaycount = fb.TitleFormat("%LASTFM_PLAYCOUNT_DB%").EvalWithMetadb(p.metadb);
3803
		this.method = this.old_userloved == 1 ? "track.unlove" : "track.love";
3804
		this.tooltip = (this.old_userloved == 1 ? "Unlove" : "Love") + " \"" + this.track + "\" by \"" + this.artist + "\".";
3805
		this.crc32 = fb.TitleFormat("$crc32($lower(%artist%%title%))").EvalWithMetadb(p.metadb);
3806
		b.update();
3807
		return true;
3808
	}
3809
	
3810
	this.playback_new_track = function() {
3811
		this.auto_love_count = 0;
3812
		this.time_elapsed = 0;
3813
		switch(true) {
3814
			case fb.PlaybackLength == 0:
3815
				this.target_time = 240;
3816
				break;
3817
			case fb.PlaybackLength >= 30:
3818
				this.target_time = Math.min(Math.floor(fb.PlaybackLength / 2), 240);
3819
				break;
3820
			default:
3821
				this.target_time = 5;
3822
				break;
3823
		}
3824
		on_item_focus_change();
3825
	}
3826
	
3827
	this.playback_edited = function() {
3828
		if (this.auto_love && fb.TitleFormat(this.auto_love_tf).Eval() == 1 && this.old_userloved == 0 && this.auto_love_count == 0) {
3829
			this.auto_love_count = 1;
3830
			p.console("Automatically loving this track....");
3831
			this.love_track();
3832
		}
3833
	}
3834
	
3835
	this.tf = function(value) {
3836
		return(value.replace(/'/g, "''").replace(/,/g, "','").replace(/\//g, "'/'").replace(/\(/g, "'('").replace(/\)/g, "')'").replace(/\[/g, "'['").replace(/\]/g, "']'"));
3837
	}
3838
	
3839
	this.love_track = function() {
3840
		l.post(this.method, p.metadb);
3841
	}
3842
	
3843
	this.sync_track = function() {
3844
		switch(true) {
3845
			case this.loved_working || this.playcount_working:
3846
				return;
3847
			case !utils.CheckComponent("foo_customdb", true):
3848
				p.console("Not contacting Last.fm. foo_customdb is missing.");
3849
				return;
3850
			default:
3851
				p.console("Contacting Last.fm....");
3852
				this.get(l.get_url() + "&method=track.getinfo&artist=" + encodeURIComponent(this.artist) + "&track=" + encodeURIComponent(this.track) + "&autocorrect=" + (l.auto_correct ? 1 : 0), function() {
3853
					ps.update_track();
3854
				});
3855
		}
3856
	}
3857
	
3858
	this.get = function(url, func) {
3859
		if (l.username.length == 0) {
3860
			this.loved_working = false;
3861
			this.playcount_working = false;
3862
			p.console(l.username_error);
3863
			return;
3864
		}
3865
		this.xmlhttp.open("GET", url, true);
3866
		this.xmlhttp.setRequestHeader('User-Agent', l.user_agent);
3867
		this.xmlhttp.send();
3868
		this.xmlhttp.onreadystatechange = function() {
3869
			if (ps.xmlhttp.readyState == 4) {
3870
				if (ps.xmlhttp.status == 200) {
3871
					func();
3872
				} else {
3873
					p.console(ps.xmlhttp.responsetext || "HTTP error: " + ps.xmlhttp.status);
3874
				}
3875
			}
3876
		}
3877
	}
3878
	
3879
	this.update_track = function() {
3880
		this.json_data = p.json_parse(ps.xmlhttp.responsetext);
3881
		if (!this.json_data || this.json_data.error > 0 || !this.json_data.track) {
3882
			p.console(ps.xmlhttp.responsetext);
3883
			return;
3884
		}
3885
		this.userplaycount = this.json_data.track.userplaycount > 0 ? ++this.json_data.track.userplaycount : 1;
3886
		this.userloved = this.json_data.track.userloved == 1 ? 1 : 0;
3887
		if (fb.IsPlaying && this.time_elapsed >= this.target_time && fb.PlaybackLength > 29 && fb.PlaybackLength < 10800) {
3888
			switch(true) {
3889
				case this.userplaycount < this.old_userplaycount:
3890
					p.console("Playcount returned from Last.fm is lower than current value. Not updating.");
3891
					break;
3892
				case this.old_userplaycount == this.userplaycount:
3893
					p.console("No changes found. Not updating.");
3894
					break;
3895
				default:
3896
					p.console("Last.fm responded ok. Attempting to update playcount...");
3897
					fb.RunContextCommandWithMetadb("Customdb Delete Playcount", p.metadb, 8);
3898
					if (this.old_userloved == 1) fb.RunContextCommandWithMetadb("Customdb Love 0", p.metadb, 8);
3899
					var attempt = 0;
3900
					while(fb.TitleFormat("%LASTFM_PLAYCOUNT_DB%").EvalWithMetadb(p.metadb) != this.userplaycount && attempt <= 3) {
3901
						var query1 = '\"INSERT INTO quicktag(url,subsong,fieldname,value) VALUES(\\"' + this.crc32 + '\\",\\"-1\\",\\"LASTFM_PLAYCOUNT_DB\\",\\"' + this.userplaycount + '\\")\";';
3902
						p.WshShell.Run(p.fso.GetFile(p.script_path + "sqlite3.exe").ShortPath + " " + p.fso.GetFile(fb.ProfilePath + "customdb_sqlite.db").ShortPath + " " + query1, 0, true);
3903
						attempt++;
3904
					}
3905
					fb.RunContextCommandWithMetadb("Customdb Refresh", p.metadb, 8);
3906
					if (fb.TitleFormat("%LASTFM_PLAYCOUNT_DB%").EvalWithMetadb(p.metadb) == this.userplaycount) p.console("Playcount updated successfully.");
3907
					else p.console("Database error. Playcount not updated.");
3908
					break;
3909
			}
3910
		}
3911
		if (this.old_userloved != this.userloved) fb.RunContextCommandWithMetadb("Customdb Love " + this.userloved, p.metadb, 8);
3912
	}
3913
	
3914
	this.start_import = function() {
3915
		if (this.show_console) fb.ShowConsole();
3916
		this.loved_page_errors = 0;
3917
		this.playcount_page_errors = 0;
3918
		ps.pages = 0;
3919
		this.r = 1;
3920
		this.sql = "BEGIN TRANSACTION;\n";
3921
		this.loved_working = true;
3922
		this.sync_loved(1);
3923
	}
3924
	
3925
	this.sync_loved = function(page) {
3926
		if (!this.loved_working) return(p.console("Import aborted."));
3927
		this.page = page;
3928
		this.get(l.get_url() + "&method=user.getlovedtracks&limit=200&page=" + this.page, function() {
3929
			ps.update_loved();
3930
		});
3931
	}
3932
	
3933
	this.update_loved = function() {
3934
		this.json_data = p.json_parse(ps.xmlhttp.responsetext);
3935
		if (this.json_data && this.json_data.error > 0) {
3936
			this.loved_working = false;
3937
			p.MsgBox("There is a problem with the Last.fm web services. Please try again later.\n\n" + ps.xmlhttp.responsetext, 0, p.name);
3938
			return;
3939
		}
3940
		if (this.json_data && this.json_data.lovedtracks && this.json_data.lovedtracks.track) {
3941
			if (this.page == 1) this.pages = this.json_data.lovedtracks["@attr"].totalPages;
3942
			for (i = 0; i < this.json_data.lovedtracks.track.length; i++) {
3943
				var data = [];
3944
				data[0] = this.json_data.lovedtracks.track[i].artist.name;
3945
				data[1] = this.json_data.lovedtracks.track[i].name;
3946
				data[2] = 1;
3947
				if (data.length == 3) {
3948
					p.console(this.r + ": " + data[0] + " - " + data[1]);
3949
					var url = fb.TitleFormat("$crc32($lower(" + this.tf(data[0]) + this.tf(data[1]) + "))").Eval(true);
3950
					this.sql += 'INSERT OR REPLACE INTO quicktag(url,subsong,fieldname,value) VALUES("' + url + '","-1","LASTFM_LOVED_DB","' + data[2] + '");' + "\n";
3951
					this.r++;
3952
				}
3953
			}
3954
			p.console("Loved tracks: completed page " + this.page + " of " + this.pages);
3955
		} else if (this.pages > 0) {
3956
			this.loved_page_errors++;
3957
		}
3958
		if (this.page < this.pages) {
3959
			this.page++;
3960
			this.sync_loved(this.page);
3961
		} else {
3962
			this.loved_working = false;
3963
			if (this.full_import) {
3964
				this.playcount_working = true;
3965
				this.pages = 0;
3966
				this.r = 1;
3967
				this.sync_playcount(1);
3968
			} else {
3969
				try {
3970
					this.sql += "COMMIT;"
3971
					var ts = p.fso.OpenTextFile(this.sql_file, 2, true, 0);
3972
					ts.WriteLine(this.sql);
3973
					ts.Close();
3974
					this.finish_import();
3975
				} catch(e) {
3976
				}
3977
				if (this.loved_page_errors > 0) {
3978
					p.console("Loved track page errors: " + this.loved_page_errors + " (200 records are lost for every page that fails.)");
3979
				} else {
3980
					p.console("There were no errors reported.");
3981
				}
3982
			}
3983
		}
3984
	}
3985
	
3986
	this.sync_playcount = function(page) {
3987
		if (this.playcount_working == false) return(p.console("Import aborted."));
3988
		this.page = page;
3989
		this.get(l.get_url() + "&method=library.gettracks&limit=100&page=" + this.page, function() {
3990
			ps.update_playcount();
3991
		});
3992
	}
3993
	
3994
	this.update_playcount = function() {
3995
		this.json_data = p.json_parse(ps.xmlhttp.responsetext);
3996
		if (this.json_data && this.json_data.error > 0) {
3997
			this.playcount_working = false;
3998
			p.MsgBox("There is a problem with the Last.fm web services. Please try again later.\n\n" + ps.xmlhttp.responsetext, 0, p.name);
3999
			return;
4000
		}
4001
		if (this.json_data && this.json_data.tracks && this.json_data.tracks.track) {
4002
			if (this.page == 1) this.pages = this.json_data.tracks["@attr"].totalPages
4003
			for (i = 0; i < this.json_data.tracks.track.length; i++) {
4004
				var data = [];
4005
				data[0] = this.json_data.tracks.track[i].artist.name;
4006
				data[1] = this.json_data.tracks.track[i].name;
4007
				data[2] = this.json_data.tracks.track[i].playcount;
4008
				if (data[2] == 0) {
4009
					this.page = this.pages;
4010
					break;
4011
				}
4012
				if (data.length == 3) {
4013
					p.console(this.r + ": " + data[0] + " - " + data[1] + " " + data[2]);
4014
					var url = fb.TitleFormat("$crc32($lower(" + this.tf(data[0]) + this.tf(data[1]) + "))").Eval(true);
4015
					this.sql += 'INSERT OR REPLACE INTO quicktag(url,subsong,fieldname,value) VALUES("' + url + '","-1","LASTFM_PLAYCOUNT_DB","' + data[2] + '");' + "\n";
4016
					this.r++;
4017
				}
4018
			}
4019
			p.console("Playcount: completed page " + this.page + " of " + this.pages);
4020
		} else if (this.pages > 0) {
4021
			this.playcount_page_errors++;
4022
		}
4023
		if (this.page < this.pages) {
4024
			this.page++;
4025
			this.sync_playcount(this.page);
4026
		} else {
4027
			try {
4028
				this.sql += "COMMIT;"
4029
				var ts = p.fso.OpenTextFile(this.sql_file, 2, true, 0);
4030
				ts.WriteLine(this.sql);
4031
				ts.Close();
4032
				this.finish_import();
4033
			} catch(e) {
4034
			}
4035
			this.playcount_working = false;
4036
			if (this.loved_page_errors + this.playcount_page_errors > 0) {
4037
				p.console("Loved track page errors: " + this.loved_page_errors + " (200 records are lost for every page that fails.)");
4038
				p.console("Playcount page errors: " + this.playcount_page_errors + " (100 records are lost for every page that fails.)");
4039
			} else {
4040
				p.console("There were no errors reported.");
4041
			}
4042
		}
4043
	}
4044
	
4045
	this.finish_import = function() {
4046
		try {
4047
			var cmd_file = p.fso.GetFile(p.script_path + "lastfm_sql.cmd").ShortPath;
4048
			var db_file = p.fso.GetFile(fb.ProfilePath + "customdb_sqlite.db").ShortPath;
4049
			p.run(cmd_file + " " + p.fso.GetFile(p.script_path + "sqlite3.exe").ShortPath + " " + db_file + " " + p.fso.GetFile(this.sql_file).ShortPath);
4050
		} catch(e) {
4051
		}
4052
	}
4053
	
4054
	this.update_button = function() {
4055
		var exclamation = this.icon == "tango" ? "exclamation.png" : "exclamation_small.png";
4056
		var love = this.icon == "tango" ? "love.png" : "love_small.png";
4057
		var love_h = this.icon == "tango" ? "love_h.png" : "love_h_small.png";
4058
		this.size = this.icon == "tango" ? 32 : 20;
4059
		switch(true) {
4060
			case l.username.length == 0:
4061
				this.n = exclamation;
4062
				this.h = exclamation;
4063
				this.tooltip = l.username_error;
4064
				this.func = null;
4065
				break;
4066
			case l.sk.length != 32:
4067
				this.n = exclamation;
4068
				this.h = exclamation;
4069
				this.tooltip = l.password_error;
4070
				this.func = null;
4071
				break;
4072
			case !p.metadb:
4073
				this.n = exclamation;
4074
				this.h = exclamation;
4075
				this.tooltip = "No selection";
4076
				this.func = null;
4077
				break;
4078
			case !utils.CheckComponent("foo_customdb", true):
4079
				this.n = exclamation;
4080
				this.h = exclamation;
4081
				this.tooltip = "The foo_customdb component is not installed. Please refer to the readme.";
4082
				this.func = null;
4083
				break;
4084
			default:
4085
				this.n = this.old_userloved == 1 ? love_h : love;
4086
				this.h = this.old_userloved == 1 ? love : love_h;
4087
				this.func = function() { ps.love_track(); }
4088
				break;
4089
		}
4090
	}
4091
	
4092
	this.x = x;
4093
	this.y = y;
4094
	this.loved_working = false;
4095
	this.playcount_working = false;
4096
	this.sql_file = p.data_folder + "lastfm.sql";
4097
	this.page = 0;
4098
	this.last_page = 0;
4099
	this.auto_love = window.GetProperty("playcount_sync_auto_love", false);
4100
	this.auto_love_tf = window.GetProperty("playcount_sync_auto_love_tf", "");
4101
	this.icon = window.GetProperty("playcount_sync_icon", "tango");
4102
	this.show_console = window.GetProperty("playcount_sync_show_console", true);
4103
	this.library = window.GetProperty("playcount_sync_library", false);
4104
	this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
4105
	window.SetInterval(function() {
4106
		var temp = ps.page > 1 ? ps.page - 1 : 1;
4107
		if (ps.loved_working && ps.page == ps.last_page) {
4108
			ps.xmlhttp.abort();
4109
			ps.sync_loved(temp);
4110
		} else if (ps.playcount_working && ps.page == ps.last_page) {
4111
			ps.xmlhttp.abort();
4112
			ps.sync_playcount(temp);
4113
		} else {
4114
			ps.last_page = ps.page;
4115
		}
4116
	}, 15000);
4117
}
4118
4119
function rating(x, y, bs) {
4120
	this.draw = function(gr) {
4121
		if (!p.metadb) return;
4122
		for (i = 1; i < 6; i++) {
4123
			this.img = i > (this.hover ? this.lrating : this.rating) ? this.off_img : this.on_img;
4124
			p.draw_image(gr, this.img, this.x + this.bs * (i - 1), this.y, this.bs, this.bs, "adjust");
4125
		}
4126
	}
4127
	
4128
	this.metadb_changed = function() {
4129
		if (!p.metadb) return false;
4130
		this.hover = false;
4131
		this.rating = p.eval("$if2(%rating%,0)");
4132
		this.tiptext = p.eval(this.tiptext_tf);
4133
		this.lrating = this.rating;
4134
		window.RepaintRect(this.x, this.y, this.w, this.bs);
4135
		return true;
4136
	}
4137
	
4138
	this.trace = function(x, y) {
4139
		return x > this.x - this.bs && x < this.x + (this.bs * 5) && y > this.y && y < this.y + this.bs;
4140
	}
4141
	
4142
	this.move = function(x, y) {
4143
		if (!this.trace(x, y)) {
4144
			if (this.hover) this.leave();
4145
			return false;
4146
		}
4147
		if (p.metadb) {
4148
			if (x > this.x) p.tt(this.tiptext);
4149
			this.hover = true;
4150
			this.lrating = Math.ceil((x - this.x) / this.bs);
4151
			window.RepaintRect(this.x, this.y, this.w, this.bs);
4152
		}
4153
		return true;
4154
	}
4155
	
4156
	this.lbtn_up = function(x, y) {
4157
		if (!this.trace(x, y)) return false;
4158
		if (this.check) {
4159
			if (this.lrating != this.rating && this.hover == 1) fb.RunContextCommandWithMetadb("Rating/" + (this.lrating == 0 ? "<not set>" : this.lrating), p.metadb, 8);
4160
		} else {
4161
			p.MsgBox(this.error_text, 0, p.name);
4162
			p.browser("http://www.foobar2000.org/components/view/foo_playcount");
4163
		}
4164
		return true;
4165
	}
4166
	
4167
	this.leave = function() {
4168
		p.ttd();
4169
		this.hover = false;
4170
		window.RepaintRect(this.x, this.y, this.w, this.bs);
4171
	}
4172
	
4173
	this.x = x;
4174
	this.y = y;
4175
	this.bs = bs;
4176
	this.w = this.bs * 5;
4177
	this.hover = false;
4178
	this.rating = null;
4179
	this.lrating = null;
4180
	this.img = null;
4181
	this.off_img = gdi.Image(p.images_path + "off.png");
4182
	this.on_img = gdi.Image(p.images_path + "on.png");
4183
	this.check = utils.CheckComponent("foo_playcount", true);
4184
	this.error_text = "This script requires foo_playcount.";
4185
	this.tiptext_tf = this.check ? 'Rate "%title%" by "%artist%"' : this.error_text;
4186
}
4187
4188
function sb(x, y, w, h, img, isVisible, func) {
4189
	this.x = x;
4190
	this.y = y;
4191
	this.w = w;
4192
	this.h = h;
4193
	this.img = img;
4194
	this.isVisible = new Function("return (" + isVisible + ");");
4195
	this.func = func;
4196
	
4197
	this.draw = function(gr) {
4198
		if (this.isVisible()) p.draw_image(gr, this.img, this.x, this.y, this.w, this.h, "adjust");
4199
	}
4200
	
4201
	this.trace = function(x, y) {
4202
		return(x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h && this.isVisible());
4203
	}
4204
	
4205
	this.lbtn_up = function(x, y) {
4206
		if (!this.trace(x, y)) return false;
4207
		this.func && this.func(x, y);
4208
		return true;
4209
	}
4210
}
4211
4212
function seekbar(x, y, w, h) {
4213
	this.trace = function(x, y) {
4214
		return (x > this.x && x < this.x + this.w && y > this.y - (this.drag ? 200 : 0) && y < this.y + this.h + (this.drag ? 200 : 0));
4215
	}
4216
	
4217
	this.draw = function(gr) {
4218
		p.draw_background(gr);
4219
		switch(this.mode) {
4220
			case "spectrogram":
4221
				if (this.working) {
4222
					p.draw_image(gr, this.hourglass_img, this.x, this.y + Math.round((this.h - 32) / 2), this.w, 32, "adjust");
4223
				} else {
4224
					p.draw_image(gr, this.img, this.x, this.y, this.w, this.h, "stretch");
4225
				}
4226
				if (fb.IsPlaying && fb.PlaybackLength > 0) {
4227
					this.calc_pos();
4228
					gr.FillSolidRect(this.x + this.pos - 2, this.y, 2, this.h, p.splitRGB(this.marker));
4229
				}
4230
				break;
4231
			case "nyan_cat":
4232
				if (fb.IsPlaying && fb.PlaybackLength > 0) {
4233
					this.calc_pos();
4234
					for (i = 0; i < this.offsets.length; i++) {
4235
						gr.FillSolidRect(this.x - 48, this.y + this.offsets[i], this.pos + 2, this.heights[i], this.colours[i]);
4236
					}
4237
					p.draw_image(gr, this.cat_img[this.z], this.pos, this.y, 48, 30);
4238
				} else {
4239
					p.draw_image(gr, this.cat_img[0], 0, this.y, 48, 30);
4240
				}
4241
				break;
4242
		}
4243
	}
4244
	
4245
	this.playback_new_track = function() {
4246
		if (this.mode != "spectrogram") return;
4247
		var metadb = fb.GetNowPlaying();
4248
		this.img && this.img.Dispose();
4249
		this.img = null;
4250
		try {
4251
			this.png_filename = spectrogram_cache + "\\" + fb.TitleFormat("$crc32(%path%)").EvalWithMetadb(metadb) + this.sox_params + ".png";
4252
			switch(true) {
4253
				case !metadb:
4254
				case metadb.RawPath.indexOf("file") != 0:
4255
					p.console("Skipping... Not a valid file type.");
4256
					break;
4257
				case fb.PlaybackLength == 0:
4258
					p.console("Skipping... Unknown length.");
4259
					break;
4260
				case fb.TitleFormat("$if($or($strcmp(%__cue_embedded%,yes),$strcmp($right(%path%,3),cue)),cue,)").EvalWithMetadb(metadb) == "cue":
4261
					p.console("Skipping... Cannot support cuesheets.");
4262
					break;
4263
				case fb.TitleFormat("%subsong%").EvalWithMetadb(metadb) > 0:
4264
					p.console("Skipping... Cannot support tracks with chapters.");
4265
					break;
4266
				case this.library && !fb.IsMetadbInMediaLibrary(metadb):
4267
					p.console("Skipping... Track not in library.");
4268
					break;
4269
				case p.fso.FileExists(this.png_filename):
4270
					this.img = gdi.Image(this.png_filename);
4271
					break;
4272
				default:
4273
					this.working = true
4274
					window.Repaint();
4275
					var filename = metadb.Path;
4276
					var length = fb.TitleFormat("%length%").EvalWithMetadb(metadb);
4277
					var cmd = "cmd /c \"\"" + ffmpeg_exe + "\" -i \"" + filename + "\" -t " + length + " -f sox - | \"" + sox_exe + "\" -p -n " + this.sox_params + " -d " + length + " -r -o \"" + this.png_filename + "\"\"";
4278
					//p.console(cmd);
4279
					try { p.WshShell.Run(cmd, 0, true); } catch(e) {}
4280
					this.working = false;
4281
					this.img = gdi.Image(this.png_filename);
4282
					break;
4283
			}
4284
		} catch(e) {
4285
			//p.console(e);
4286
		}
4287
		window.Repaint();
4288
	}
4289
	
4290
	this.playback_stop = function() {
4291
		window.Repaint();
4292
	}
4293
	
4294
	this.playback_seek = function() {
4295
		this.update();
4296
	}
4297
	
4298
	this.move = function(x, y) {
4299
		if (this.drag) this.update();
4300
		if (this.trace(x, y)) {
4301
			if (fb.IsPlaying && fb.PlaybackLength > 0) {
4302
				x -= this.x;
4303
				this.drag_seek = x < 0 ? 0 : x > this.w ? 1 : x / this.w;
4304
				if (x != this.old_x || y != this.old_y) {
4305
					p.tt(p.format_time(fb.PlaybackLength * this.drag_seek));
4306
					this.old_x = x;
4307
					this.old_y = y;
4308
				}
4309
			}
4310
			return true;
4311
		} else {
4312
			this.leave();
4313
			return false;
4314
		}
4315
	}
4316
	
4317
	this.lbtn_down = function(x, y) {
4318
		if (!this.trace(x, y)) return false;
4319
		if (fb.IsPlaying && fb.PlaybackLength > 0) this.drag = true;
4320
		return true;
4321
	}
4322
	
4323
	this.lbtn_up = function(x, y) {
4324
		if (!this.trace(x, y)) return false;
4325
		if (this.drag) {
4326
			this.drag = false;
4327
			fb.PlaybackTime = fb.PlaybackLength * this.drag_seek;
4328
		}
4329
		return true;
4330
	}
4331
	
4332
	this.leave = function() {
4333
		this.drag = false;
4334
		p.ttd();
4335
	}
4336
	
4337
	this.update = function() {
4338
		window.RepaintRect(0, this.y, p.w, this.h);
4339
	}
4340
	
4341
	this.calc_pos = function() {
4342
		this.pos = this.drag ? this.w * this.drag_seek : this.w * (fb.PlaybackTime / fb.PlaybackLength);
4343
	}
4344
	
4345
	this.init = function() {
4346
		switch(true) {
4347
			case p.check_feature("spectrogram"):
4348
				this.clear_images = function(period) {
4349
					var now = Date.parse(Date());
4350
					images = utils.Glob(spectrogram_cache + "\\*.*").toArray();
4351
					for (i = 0; i < images.length; i++) {
4352
						if (this.png_filename == images[i]) continue;
4353
						var file = p.fso.Getfile(images[i]);
4354
						var file_date = Date.parse(file.DateLastModified);
4355
						if (now - file_date > period) {
4356
							try {
4357
								p.fso.DeleteFile(images[i]);
4358
							} catch(e) {
4359
								p.console("Could not delete " + images[i]);
4360
							}
4361
						}
4362
					}
4363
				}
4364
				
4365
				this.mode = "spectrogram";
4366
				this.library = window.GetProperty("seekbar_library", false);
4367
				this.marker = window.GetProperty("seekbar_marker", "240-240-240");
4368
				this.sox_params = window.GetProperty("sox_params", "channels 1 spectrogram -Y 130").trim();
4369
				this.working = false;
4370
				this.img = false;
4371
				this.hourglass_img = gdi.Image(p.images_path + "hourglass.png");
4372
				//if (!p.fso.FolderExists(spectrogram_cache)) p.fso.CreateFolder(spectrogram_cache);
4373
				if (fb.IsPlaying) {
4374
					window.SetTimeout(function() {
4375
						s.playback_new_track();
4376
					}, 100);
4377
				}
4378
				break;
4379
			case p.check_feature("nyan_cat"):
4380
				this.mode = "nyan_cat";
4381
				this.cat_img = [gdi.Image(p.images_path + "\\seekbar cat.png"), gdi.Image(p.images_path + "\\seekbar cat 2.png")];
4382
				this.offsets = [2, 6, 10, 15, 20, 24];
4383
				this.heights = [4, 4, 5, 5, 4, 4];
4384
				this.colours = [RGB(255, 0, 0), RGB(255, 153, 0), RGB(255, 255, 0), RGB(51, 255, 0), RGB(0, 153, 255), RGB(102, 51, 255)];
4385
				break;
4386
		}
4387
	}
4388
	
4389
	this.x = x;
4390
	this.y = y;
4391
	this.w = w;
4392
	this.h = h;
4393
	this.z = 0;
4394
	this.pos = 0;
4395
	this.drag = false;
4396
	this.drag_seek = 0;
4397
	this.old_x = 0;
4398
	this.old_y = 0;
4399
	this.init();
4400
	this.seekbar_timer = window.SetInterval(function() {
4401
		s.z = s.z == 0 ? 1 : 0;
4402
		if (!fb.IsPlaying || fb.IsPaused || fb.PlaybackLength == 0) return;
4403
		s.update();
4404
	}, 150);
4405
}
4406
4407
function text(x, y, w, h) {
4408
	this.size = function() {
4409
		this.rows = Math.floor((this.h - 36) / p.row_height);
4410
		this.but_x = this.x + Math.round((this.w - 15) / 2);
4411
		this.up_btn = new sb(this.but_x, this.y, 15, 15, p.up_img, "t.offset > 0", function() { t.wheel(1); });
4412
		this.down_btn = new sb(this.but_x, this.y + this.h - 15, 15, 15, p.down_img, "t.offset < t.text_rows - t.rows", function() { t.wheel(-1); });
4413
		this.calc();
4414
	}
4415
	
4416
	this.draw = function(gr, colour) {
4417
		for (i = 0; i < Math.min(this.rows, this.text_rows); i++) {
4418
			if (this.centre) p.centre_text(gr, this.text_array[i + this.offset], this.fixed ? p.fixed_font : p.normal_font, colour || p.textcolour, this.x, 18 + this.y + (i * p.row_height), this.w, p.row_height);
4419
			else p.left_text(gr, this.text_array[i + this.offset], this.fixed ? p.fixed_font : p.normal_font, colour || p.textcolour, this.x, 18 + this.y + (i * p.row_height), this.w, p.row_height);
4420
		}
4421
		this.up_btn.draw(gr);
4422
		this.down_btn.draw(gr);
4423
	}
4424
	
4425
	this.metadb_changed = function() {
4426
		if (!p.metadb) return false;
4427
		switch(this.mode) {
4428
			case "simple_tag":
4429
				this.temp_filename = p.metadb.Path;
4430
				if (this.filename == this.temp_filename) return false;
4431
				this.filename = this.temp_filename;
4432
				this.text = p.eval(this.tag);
4433
				break;
4434
			case "simple_text":
4435
				this.temp_filename = p.eval(this.filename_tf);
4436
				if (this.filename == this.temp_filename) return false;
4437
				this.text = "";
4438
				this.filename = this.temp_filename;
4439
				if (p.fso.FolderExists(this.filename)) {
4440
					this.files = [];
4441
					this.files = this.files.concat(utils.Glob(this.filename + "\\*.txt").toArray(), utils.Glob(this.filename + "\\*.log").toArray());
4442
					this.files.sort();
4443
					this.text = p.open(this.files[0]);
4444
				} else {
4445
					this.filenames = this.filename.split("|");
4446
					for (i = 0; i < this.filenames.length; i++) {
4447
						if (p.fso.fileExists(this.filenames[i])) {
4448
							this.text = p.open(this.filenames[i]);
4449
							break;
4450
						}
4451
					}
4452
				}
4453
				this.text = this.text.replace(/\t/g, "    ");
4454
				break;
4455
			case "lastfm_wiki":
4456
				p.artist = p.eval(p.artist_tf);
4457
				if (this.artist == p.artist) return false;
4458
				this.artist = p.artist;
4459
				this.folder = p.data_folder + p.artist;
4460
				if (!p.fso.FolderExists(this.folder)) p.fso.CreateFolder(this.folder);
4461
				this.filename = this.folder + "\\artist.getInfo_mod.json";
4462
				this.text = "Nothing found.";
4463
				this.url = "http://www.last.fm/";
4464
				if (p.fso.fileExists(this.filename)) {
4465
					this.json_text = p.open(this.filename);
4466
					this.json_data = p.json_parse(this.json_text);
4467
					if (this.json_data && this.json_data.response && this.json_data.response.biographies) {
4468
						this.items = this.json_data.response.biographies.length;
4469
						for (i = 0; i < this.items; i++) {
4470
							if (this.json_data.response.biographies[i].site == this.source) {
4471
								this.text = this.json_data.response.biographies[i].text;
4472
								this.url = this.json_data.response.biographies[i].license["attribution-url"];
4473
								break;
4474
							}
4475
						}
4476
						if (this.source == "last.fm") this.text = this.text.replace(/\.  /g, ".\n\n");
4477
						if (this.source == "wikipedia") this.text = this.text.replace(/\. \n/g, ".\n\n").replace(/\n\n\n/g, "\n\n").replace(/ edit:\n/g , ":\n").replace(/edit:\n/g , ":\n");
4478
					}
4479
				} else {
4480
					this.get();
4481
				}
4482
				break;
4483
			case "lastfm_album":
4484
				var temp_album = p.eval("[%album%]");
4485
				var temp_artist = p.eval("[%album artist%]");
4486
				if (this.album == temp_album && this.artist == temp_artist) return false;
4487
				this.artist = temp_artist;
4488
				this.album = temp_album;
4489
				this.folder = p.data_folder + p.eval("$crc32(%album artist%)");
4490
				if (!p.fso.FolderExists(this.folder)) p.fso.CreateFolder(this.folder);
4491
				this.filename = this.folder + "\\album.getInfo_" + p.eval("$crc32(%album%)") + ".json";
4492
				this.text = "Nothing found.";
4493
				this.url = l.url;
4494
				if (p.fso.fileExists(this.filename)) {
4495
					this.file = p.fso.GetFile(this.filename);
4496
					this.json_text = p.open(this.filename);
4497
					this.json_data = p.json_parse(this.json_text);
4498
					if (this.json_data && this.json_data.album) {
4499
						if (this.json_data.album.url) this.url = this.json_data.album.url;
4500
						if (this.json_data.album.wiki && this.json_data.album.wiki.content) {
4501
							this.text = p.strip_tags(this.json_data.album.wiki.content);
4502
							this.text = this.text.replace("User-contributed text is available under the Creative Commons By-SA License and may also be available under the GNU FDL.", "").trim();
4503
						}
4504
					}
4505
					if (Date.parse(Date()) - Date.parse(this.file.DateLastModified) > ONE_DAY) this.get();
4506
				} else {
4507
					this.get();
4508
				}
4509
				break;
4510
		}
4511
		this.calc();
4512
		window.Repaint();
4513
		return true;
4514
	}
4515
	
4516
	this.trace = function(x, y) {
4517
		return (x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h);
4518
	}
4519
	
4520
	this.wheel = function(step) {
4521
		if (!this.trace(p.mx, p.my)) return false;
4522
		if (this.text_rows > this.rows) {
4523
			this.offset -= step * 3;
4524
			if (this.offset < 0) this.offset = 0;
4525
			if (this.offset + this.rows > this.text_rows) this.offset = this.text_rows - this.rows;
4526
			window.RepaintRect(this.x, this.y, this.w, this.h);
4527
		}
4528
		return true;
4529
	}
4530
	
4531
	this.move = function(x, y) {
4532
		switch(true) {
4533
			case !this.trace(x, y):
4534
				window.SetCursor(IDC_ARROW);
4535
				return false;
4536
			case this.up_btn.trace(x, y):
4537
			case this.down_btn.trace(x, y):
4538
				window.SetCursor(IDC_HAND);
4539
				return true;
4540
			default:
4541
				window.SetCursor(IDC_ARROW);
4542
				return false;
4543
		}
4544
	}
4545
	
4546
	this.lbtn_up = function(x, y) {
4547
		if (!this.trace(x, y)) return false;
4548
		this.up_btn.lbtn_up(x, y);
4549
		this.down_btn.lbtn_up(x, y);
4550
		return true;
4551
	}
4552
	
4553
	this.get = function() {
4554
		var fn = this.filename;
4555
		var func = function() {
4556
			if (!p.save(t.xmlhttp.responsetext, fn)) return;
4557
			t.artist = "";
4558
			t.album = "";
4559
			on_item_focus_change();
4560
		}
4561
		var url = "";
4562
		var user_agent = "";
4563
		switch(this.mode) {
4564
			case "lastfm_album":
4565
				if (this.artist == "" || this.album == "") return;
4566
				url = l.get_url() + "&method=album.getInfo&artist=" + encodeURIComponent(this.artist) + "&album=" + encodeURIComponent(this.album);
4567
				user_agent = l.user_agent;
4568
				break;
4569
			case "lastfm_wiki":
4570
				if (this.artist == "" || this.artist == "?") return;
4571
				url = "http://developer.echonest.com/api/v4/artist/biographies?api_key=EKWS4ESQLKN3G2ZWV&format=json&name=" + encodeURIComponent(this.artist);
4572
				break;
4573
		}
4574
		if (url.length == 0) return;
4575
		this.xmlhttp.open("GET", url, true);
4576
		if (user_agent.length > 0) this.xmlhttp.setRequestHeader('User-Agent', user_agent);
4577
		this.xmlhttp.send();
4578
		this.xmlhttp.onreadystatechange = function() {
4579
			if (t.xmlhttp.readyState == 4) {
4580
				if (t.xmlhttp.status == 200) {
4581
					func();
4582
				} else {
4583
					p.console(t.xmlhttp.responsetext || "HTTP error: " + t.xmlhttp.status);
4584
				}
4585
			}
4586
		}
4587
	}
4588
	
4589
	this.calc = function() {
4590
		this.offset = 0;
4591
		this.text_rows = 0;
4592
		if (this.w < 100 || this.text.length == 0) return;
4593
		var temp_bmp = gdi.CreateImage(1, 1);
4594
		var temp_gr = temp_bmp.GetGraphics();
4595
		var paragraphs = this.text.split("\n");
4596
		this.text_array = [];
4597
		for (i = 0; i < paragraphs.length; i++) {
4598
			if (this.fixed) {
4599
				this.text_array.push(paragraphs[i]);
4600
			} else {
4601
				var lines = temp_gr.EstimateLineWrap(paragraphs[i], p.normal_font, this.w).toArray();
4602
				for (j = 0; j < lines.length; j += 2) {
4603
					this.text_array.push(lines[j].trim());
4604
				}
4605
			}
4606
		}
4607
		this.text_rows = this.text_array.length;
4608
		temp_bmp.ReleaseGraphics(temp_gr);
4609
		temp_bmp.Dispose();
4610
		temp_gr = null;
4611
		temp_bmp = null;
4612
	}
4613
	
4614
	this.init = function() {
4615
		switch(true) {
4616
			case p.check_feature("lastfm_album"):
4617
				this.mode = "lastfm_album";
4618
				break;
4619
			case p.check_feature("lastfm_wiki"):
4620
				this.mode = "lastfm_wiki";
4621
				this.source = window.GetProperty("biography_source", "last.fm");
4622
				break;
4623
			case p.check_feature("simple_text"):
4624
				this.mode = "simple_text";
4625
				this.title = window.GetProperty("text_title", "$directory_path(%path%)");
4626
				this.filename_tf = window.GetProperty("text_filename_tf", "$directory_path(%path%)");
4627
				this.filename = "";
4628
				this.fixed = window.GetProperty("text_fixed_font", true);
4629
				break;
4630
			case p.check_feature("simple_tag"):
4631
				this.mode = "simple_tag";
4632
				this.title = window.GetProperty("text_title", "%title%");
4633
				this.filename = "";
4634
				this.centre = window.GetProperty("text_centre", false);
4635
				this.tag = window.GetProperty("text_tag", "[%lyrics%]");
4636
				break;
4637
		}
4638
	}
4639
	
4640
	this.x = x;
4641
	this.y = y;
4642
	this.w = w;
4643
	this.h = h;
4644
	this.text = "";
4645
	this.artist = "";
4646
	this.album = "";
4647
	this.url = "";
4648
	this.fixed = false;
4649
	this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
4650
	this.init();
4651
	this.size();
4652
}
4653
4654
function thumbs() {
4655
	this.trace = function(x, y) {
4656
		return (x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h);
4657
	}
4658
	
4659
	this.draw = function(gr) {
4660
		switch(true) {
4661
			case im.images.length == 0:
4662
				break;
4663
			case this.mode == "off":
4664
				p.draw_image(gr, im.images[im.index], im.x, im.y, im.w, im.h, im.type);
4665
				break;
4666
			case !this.img:
4667
				break;
4668
			case this.mode == "grid":
4669
				gr.DrawImage(this.img, this.x, this.y, this.w, this.h, 0, this.offset * this.px, this.w, this.h);
4670
				if (this.overlay) {
4671
					gr.FillSolidRect(this.x, this.y, this.w, this.h, RGBA(0, 0, 0, 126));
4672
					p.draw_image(gr, im.images[im.index], im.x, im.y, im.w, im.h, "adjust");
4673
				}
4674
				break;
4675
			case this.mode == "left":
4676
			case this.mode == "right":
4677
				gr.DrawImage(this.img, this.x, this.y, this.w, this.h, 0, this.offset * this.px, this.w, this.h);
4678
				p.draw_image(gr, im.images[im.index], im.x, im.y, im.w, im.h, im.type);
4679
				break;
4680
			case this.mode == "bottom":
4681
			case this.mode == "top":
4682
				gr.DrawImage(this.img, this.x, this.y, this.w, this.h, this.offset * this.px, 0, this.w, this.h);
4683
				p.draw_image(gr, im.images[im.index], im.x, im.y, im.w, im.h, im.type);
4684
				break;
4685
		}
4686
	}
4687
	
4688
	this.calc = function() {
4689
		this.offset = 0;
4690
		switch(true) {
4691
			case p.w < this.px || p.h < this.px || this.mode == "off":
4692
				this.nc = true;
4693
				this.img && this.img.Dispose();
4694
				this.img = null;
4695
				im.x = 0;
4696
				im.y = 0;
4697
				im.w = p.w;
4698
				im.h = p.h;
4699
				break;
4700
			case this.mode == "grid":
4701
				this.x = 0;
4702
				this.y = 0;
4703
				this.w = p.w;
4704
				this.h = p.h;
4705
				im.x = 40;
4706
				im.y = 40;
4707
				im.w = this.w - 80;
4708
				im.h = this.h - 80;
4709
				if (!this.nc && this.columns != Math.floor(this.w / this.px)) this.nc = true;
4710
				this.overlay = false;
4711
				this.rows = Math.ceil(this.h / this.px);
4712
				this.columns = Math.floor(this.w / this.px);
4713
				this.img_rows = Math.ceil(im.images.length / this.columns);
4714
				if (this.nc && im.images.length > 0) {
4715
					this.nc = false;
4716
					this.img && this.img.Dispose();
4717
					this.img = null;
4718
					this.img = gdi.CreateImage(Math.min(this.columns, im.images.length) * this.px, this.img_rows * this.px);
4719
					var temp_gr = this.img.GetGraphics();
4720
					temp_gr.SetInterpolationMode(7);
4721
					var ci = 0;
4722
					var row, col;
4723
					for (row = 0; row < this.img_rows; row++) {
4724
						for (col = 0; col < this.columns; col++) {
4725
							if (ci == im.images.length) continue;
4726
							p.draw_image(temp_gr, im.images[ci], col * this.px, row * this.px, this.px, this.px, "top");
4727
							ci++;
4728
						}
4729
					}
4730
					this.img.ReleaseGraphics(temp_gr);
4731
					temp_gr = null;
4732
				}
4733
				break;
4734
			case this.mode == "left":
4735
			case this.mode == "right":
4736
				this.x = this.mode == "left" ? 0 : p.w - this.px;
4737
				this.y = 0;
4738
				this.w = this.px;
4739
				this.h = p.h;
4740
				im.x = this.mode == "right" ? 0 : this.px;
4741
				im.y = 0;
4742
				im.w = p.w - this.px;
4743
				im.h = p.h;
4744
				this.rows = Math.ceil(this.h / this.px);
4745
				if (this.nc && im.images.length > 0) {
4746
					this.nc = false;
4747
					this.img && this.img.Dispose();
4748
					this.img = null;
4749
					this.img = gdi.CreateImage(this.px, this.px * im.images.length);
4750
					var temp_gr = this.img.GetGraphics();
4751
					temp_gr.SetInterpolationMode(7);
4752
					for (i = 0; i < im.images.length; i++) {
4753
						p.draw_image(temp_gr, im.images[i], 0, i * this.px, this.px, this.px, "top");
4754
					}
4755
					this.img.ReleaseGraphics(temp_gr);
4756
					temp_gr = null;
4757
				}
4758
				break;
4759
			case this.mode == "bottom":
4760
			case this.mode == "top":
4761
				this.x = 0;
4762
				this.y = this.mode == "top" ? 0 : p.h - this.px;
4763
				this.w = p.w;
4764
				this.h = this.px;
4765
				im.x = 0;
4766
				im.y = this.mode == "bottom" ? 0 : this.px;
4767
				im.w = p.w;
4768
				im.h = p.h - this.px;
4769
				this.columns = Math.ceil(this.w / this.px);
4770
				if (this.nc && im.images.length > 0) {
4771
					this.nc = false;
4772
					this.img && this.img.Dispose();
4773
					this.img = null;
4774
					this.img = gdi.CreateImage(this.px * im.images.length, this.px);
4775
					var temp_gr = this.img.GetGraphics();
4776
					temp_gr.SetInterpolationMode(7);
4777
					for (i = 0; i < im.images.length; i++) {
4778
						p.draw_image(temp_gr, im.images[i], i * this.px, 0, this.px, this.px, "top");
4779
					}
4780
					this.img.ReleaseGraphics(temp_gr);
4781
					temp_gr = null;
4782
				}
4783
				break;
4784
		}
4785
	}
4786
	
4787
	this.wheel = function(step) {
4788
		switch(true) {
4789
			case !this.trace(p.mx, p.my):
4790
			case this.overlay:
4791
				return false;
4792
			case this.mode == "grid":
4793
				if (this.img_rows < this.rows) return true;
4794
				this.offset -= step;
4795
				if (this.offset < 0) this.offset = 0;
4796
				if (this.offset > this.img_rows - this.rows) this.offset = this.img_rows - this.rows + 1;
4797
				break;
4798
			case this.mode == "left":
4799
			case this.mode == "right":
4800
				if (im.images.length < this.rows) return true;
4801
				this.offset -= step;
4802
				if (this.offset < 0) this.offset = 0;
4803
				if (this.rows + this.offset > im.images.length) this.offset = im.images.length - this.rows + 1;
4804
				break;
4805
			case this.mode == "bottom":
4806
			case this.mode == "top":
4807
				if (im.images.length < this.columns) return true;
4808
				this.offset -= step;
4809
				if (this.offset < 0) this.offset = 0;
4810
				if (this.columns + this.offset > im.images.length) this.offset = im.images.length - this.columns + 1;
4811
				break;
4812
		}
4813
		window.RepaintRect(this.x, this.y, this.w, this.h);
4814
		return true;
4815
	}
4816
	
4817
	this.move = function(x, y) {
4818
		switch(true) {
4819
			case !this.trace(x, y):
4820
				window.SetCursor(IDC_ARROW);
4821
				return false;
4822
			case this.overlay:
4823
				window.SetCursor(IDC_ARROW);
4824
				return true;
4825
			case this.mode == "grid":
4826
				this.index = Math.floor((x - this.x) / this.px) + (Math.floor((y - this.y) / this.px) * this.columns) + (this.offset * this.columns);
4827
				break;
4828
			case this.mode == "left":
4829
			case this.mode == "right":
4830
				this.index = Math.floor((y - this.y) / this.px) + this.offset;
4831
				break;
4832
			case this.mode == "bottom":
4833
			case this.mode == "top":
4834
				this.index = Math.floor((x - this.x) / this.px) + this.offset;
4835
				break;
4836
		}
4837
		window.SetCursor(this.index < im.images.length ? IDC_HAND : IDC_ARROW);
4838
		return true;
4839
	}
4840
	
4841
	this.lbtn_up = function(x, y) {
4842
		switch(true) {
4843
			case !this.trace(x, y):
4844
				return false;
4845
			case this.mode == "grid" && this.overlay && im.trace(x, y):
4846
				this.overlay = false;
4847
				window.Repaint();
4848
				break;
4849
			case this.mode == "grid" && this.index < im.images.length && !this.overlay:
4850
				this.overlay = true;
4851
				im.index = this.index;
4852
				window.Repaint();
4853
				break;
4854
			case this.overlay:
4855
				break;
4856
			case this.index < im.images.length:
4857
				im.index = this.index;
4858
				window.Repaint();
4859
		}
4860
		return true;
4861
	}
4862
	
4863
	this.lbtn_dblclk = function(x, y) {
4864
		if (!im.trace(x, y) || th.mode == "grid") return false;
4865
		p.run("\"" + im.files[im.index] + "\"");
4866
		return true;
4867
	}
4868
	
4869
	this.nc = false;
4870
	this.mode = "off";
4871
	this.px = 40;
4872
	this.img = null;
4873
}
4874
4875
//json2.js
4876
if(typeof JSON!=='object'){JSON={};}
4877
(function(){'use strict';function f(n){return n<10?'0'+n:n;}
4878
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
4879
f(this.getUTCMonth()+1)+'-'+
4880
f(this.getUTCDate())+'T'+
4881
f(this.getUTCHours())+':'+
4882
f(this.getUTCMinutes())+':'+
4883
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
4884
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
4885
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
4886
if(typeof rep==='function'){value=rep.call(holder,key,value);}
4887
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
4888
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
4889
v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}
4890
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]==='string'){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
4891
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
4892
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
4893
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
4894
return str('',{'':value});};}
4895
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
4896
return reviver.call(holder,key,value);}
4897
text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
4898
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
4899
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
4900
throw new SyntaxError('JSON.parse');};}}());
4901
4902
/*
4903
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
4904
 * Digest Algorithm, as defined in RFC 1321.
4905
 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
4906
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
4907
 * Distributed under the BSD License
4908
 * See http://pajhome.org.uk/crypt/md5 for more info.
4909
 */
4910
var hexcase=0;function hex_md5(a){return rstr2hex(rstr_md5(str2rstr_utf8(a)))}
4911
function hex_hmac_md5(a,b){return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a),str2rstr_utf8(b)))}
4912
function md5_vm_test(){return hex_md5("abc").toLowerCase()=="900150983cd24fb0d6963f7d28e17f72"}
4913
function rstr_md5(a){return binl2rstr(binl_md5(rstr2binl(a),a.length*8))}
4914
function rstr_hmac_md5(c,f){var e=rstr2binl(c);if(e.length>16){e=binl_md5(e,c.length*8)}
4915
var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}
4916
var g=binl_md5(a.concat(rstr2binl(f)),512+f.length*8);return binl2rstr(binl_md5(d.concat(g),512+128))}
4917
function rstr2hex(c){try{hexcase}catch(g){hexcase=0}
4918
var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}
4919
return b}
4920
function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}
4921
if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}
4922
return b}
4923
function rstr2binl(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}
4924
for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(c%32)}
4925
return a}
4926
function binl2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(c%32))&255)}
4927
return a}
4928
function binl_md5(p,k){p[k>>5]|=128<<((k)%32);p[(((k+64)>>>9)<<4)+14]=k;var o=1732584193;var n=-271733879;var m=-1732584194;var l=271733878;for(var g=0;g<p.length;g+=16){var j=o;var h=n;var f=m;var e=l;o=md5_ff(o,n,m,l,p[g+0],7,-680876936);l=md5_ff(l,o,n,m,p[g+1],12,-389564586);m=md5_ff(m,l,o,n,p[g+2],17,606105819);n=md5_ff(n,m,l,o,p[g+3],22,-1044525330);o=md5_ff(o,n,m,l,p[g+4],7,-176418897);l=md5_ff(l,o,n,m,p[g+5],12,1200080426);m=md5_ff(m,l,o,n,p[g+6],17,-1473231341);n=md5_ff(n,m,l,o,p[g+7],22,-45705983);o=md5_ff(o,n,m,l,p[g+8],7,1770035416);l=md5_ff(l,o,n,m,p[g+9],12,-1958414417);m=md5_ff(m,l,o,n,p[g+10],17,-42063);n=md5_ff(n,m,l,o,p[g+11],22,-1990404162);o=md5_ff(o,n,m,l,p[g+12],7,1804603682);l=md5_ff(l,o,n,m,p[g+13],12,-40341101);m=md5_ff(m,l,o,n,p[g+14],17,-1502002290);n=md5_ff(n,m,l,o,p[g+15],22,1236535329);o=md5_gg(o,n,m,l,p[g+1],5,-165796510);l=md5_gg(l,o,n,m,p[g+6],9,-1069501632);m=md5_gg(m,l,o,n,p[g+11],14,643717713);n=md5_gg(n,m,l,o,p[g+0],20,-373897302);o=md5_gg(o,n,m,l,p[g+5],5,-701558691);l=md5_gg(l,o,n,m,p[g+10],9,38016083);m=md5_gg(m,l,o,n,p[g+15],14,-660478335);n=md5_gg(n,m,l,o,p[g+4],20,-405537848);o=md5_gg(o,n,m,l,p[g+9],5,568446438);l=md5_gg(l,o,n,m,p[g+14],9,-1019803690);m=md5_gg(m,l,o,n,p[g+3],14,-187363961);n=md5_gg(n,m,l,o,p[g+8],20,1163531501);o=md5_gg(o,n,m,l,p[g+13],5,-1444681467);l=md5_gg(l,o,n,m,p[g+2],9,-51403784);m=md5_gg(m,l,o,n,p[g+7],14,1735328473);n=md5_gg(n,m,l,o,p[g+12],20,-1926607734);o=md5_hh(o,n,m,l,p[g+5],4,-378558);l=md5_hh(l,o,n,m,p[g+8],11,-2022574463);m=md5_hh(m,l,o,n,p[g+11],16,1839030562);n=md5_hh(n,m,l,o,p[g+14],23,-35309556);o=md5_hh(o,n,m,l,p[g+1],4,-1530992060);l=md5_hh(l,o,n,m,p[g+4],11,1272893353);m=md5_hh(m,l,o,n,p[g+7],16,-155497632);n=md5_hh(n,m,l,o,p[g+10],23,-1094730640);o=md5_hh(o,n,m,l,p[g+13],4,681279174);l=md5_hh(l,o,n,m,p[g+0],11,-358537222);m=md5_hh(m,l,o,n,p[g+3],16,-722521979);n=md5_hh(n,m,l,o,p[g+6],23,76029189);o=md5_hh(o,n,m,l,p[g+9],4,-640364487);l=md5_hh(l,o,n,m,p[g+12],11,-421815835);m=md5_hh(m,l,o,n,p[g+15],16,530742520);n=md5_hh(n,m,l,o,p[g+2],23,-995338651);o=md5_ii(o,n,m,l,p[g+0],6,-198630844);l=md5_ii(l,o,n,m,p[g+7],10,1126891415);m=md5_ii(m,l,o,n,p[g+14],15,-1416354905);n=md5_ii(n,m,l,o,p[g+5],21,-57434055);o=md5_ii(o,n,m,l,p[g+12],6,1700485571);l=md5_ii(l,o,n,m,p[g+3],10,-1894986606);m=md5_ii(m,l,o,n,p[g+10],15,-1051523);n=md5_ii(n,m,l,o,p[g+1],21,-2054922799);o=md5_ii(o,n,m,l,p[g+8],6,1873313359);l=md5_ii(l,o,n,m,p[g+15],10,-30611744);m=md5_ii(m,l,o,n,p[g+6],15,-1560198380);n=md5_ii(n,m,l,o,p[g+13],21,1309151649);o=md5_ii(o,n,m,l,p[g+4],6,-145523070);l=md5_ii(l,o,n,m,p[g+11],10,-1120210379);m=md5_ii(m,l,o,n,p[g+2],15,718787259);n=md5_ii(n,m,l,o,p[g+9],21,-343485551);o=safe_add(o,j);n=safe_add(n,h);m=safe_add(m,f);l=safe_add(l,e)}
4929
return Array(o,n,m,l)}
4930
function md5_cmn(h,e,d,c,g,f){return safe_add(bit_rol(safe_add(safe_add(e,h),safe_add(c,f)),g),d)}
4931
function md5_ff(g,f,k,j,e,i,h){return md5_cmn((f&k)|((~f)&j),g,f,e,i,h)}
4932
function md5_gg(g,f,k,j,e,i,h){return md5_cmn((f&j)|(k&(~j)),g,f,e,i,h)}
4933
function md5_hh(g,f,k,j,e,i,h){return md5_cmn(f^k^j,g,f,e,i,h)}
4934
function md5_ii(g,f,k,j,e,i,h){return md5_cmn(k^(f|(~j)),g,f,e,i,h)}
4935
function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}
4936
function bit_rol(a,b){return(a<<b)|(a>>>(32-b))};
4937
4938
4939
4940
4941
4942
var p = new panel("Youtube Radio", ["custom_background", "remap", "metadb"]);
4943
var im = new images(0, 0, 0, 0);
4944
var th = new thumbs();
4945
4946
on_item_focus_change();
4947
4948
function on_playback_time(time) {
4949
    im.playback_time(time);
4950
//if (ooo2 == "" || ooo2 == "?") if (time==30) im.downloadLFM1();
4951
}
4952
4953
4954
function on_metadb_changed() {
4955
	im.metadb_changed();
4956
}
4957
4958
//Button
4959
4960
var Buttons;
4961
4962
var g_tooltip = window.CreateTooltip();
4963
var g_down = false;
4964
4965
var btn_down = null;
4966
var cur_btn = null;
4967
4968
ButtonStates = {
4969
	normal: 0,
4970
	hover: 1,
4971
	down: 2
4972
}
4973
4974
function Button(x, y, w, h, img_src, func, tiptext)  {
4975
	this.left = x;
4976
	this.top = y;
4977
	this.w = w;
4978
	this.h = h;
4979
	this.right = x + w;
4980
	this.bottom = y + h;
4981
	this.func = func;
4982
	this.tiptext = tiptext;
4983
	this.state = ButtonStates.normal;
4984
	this.img_normal = img_src && img_src.normal ? gdi.Image(img_src.normal) : null;
4985
	this.img_hover = img_src && img_src.hover ? gdi.Image(img_src.hover) : this.img_normal;
4986
	this.img_down = img_src && img_src.down ? gdi.Image(img_src.down) : this.img_hover;
4987
	this.img = this.img_normal;
4988
	
4989
	this.alterImage = function(img_src) {
4990
		this.img_normal = img_src && img_src.normal ? gdi.Image(img_src.normal) : null;
4991
		this.img_hover = img_src && img_src.hover ? gdi.Image(img_src.hover) : this.img_normal;
4992
		this.img_down = img_src && img_src.down ? gdi.Image(img_src.down) : this.img_hover;
4993
		
4994
		this.changeState(this.state);
4995
	}
4996
	
4997
	this.traceMouse = function (x, y) {
4998
		var b = (this.left < x) && (x < this.right) && (this.top < y) && (y < this.bottom);
4999
		if (b)
5000
			g_down ? this.changeState(ButtonStates.down) : this.changeState(ButtonStates.hover);
5001
		else
5002
			this.changeState(ButtonStates.normal);
5003
		return b;
5004
	}
5005
	
5006
	
5007
	this.changeState = function (newstate) {
5008
		if (newstate != this.state)
5009
			window.RepaintRect(this.left, this.top, this.w, this.h);
5010
		this.state = newstate;
5011
		switch (this.state)
5012
		{
5013
		case ButtonStates.normal:
5014
			this.img = this.img_normal;
5015
			break;
5016
			
5017
		case ButtonStates.hover:
5018
			this.img = this.img_hover;
5019
			break;
5020
			
5021
		case ButtonStates.down:
5022
			this.img = this.img_down;
5023
			break;
5024
			
5025
		default:
5026
			this.img = null;
5027
		}
5028
	}
5029
	
5030
	this.draw = function (gr) {
5031
		this.img && gr.DrawImage(this.img, this.left, this.top, this.w, this.h, 0, 0, this.w, this.h);
5032
	}
5033
	
5034
	this.onClick = function () {
5035
		this.func && this.func(x,y);
5036
	}
5037
	
5038
	this.onMouseIn = function() {
5039
		g_tooltip.Text = this.tiptext;
5040
		g_tooltip.Activate();
5041
	}
5042
	
5043
	this.onMouseOut = function() {
5044
		g_tooltip.Deactivate();
5045
	}
5046
}
5047
5048
function buttonsDraw(gr) {
5049
	for (i in Buttons) {
5050
		Buttons[i].draw(gr);
5051
	}
5052
}
5053
5054
function buttonsTraceMouse(x, y) {
5055
	var btn = null;
5056
	for (i in Buttons) {
5057
		if (Buttons[i].traceMouse(x, y) && !btn)
5058
			btn = Buttons[i];
5059
	}
5060
5061
	return btn;
5062
}
5063
5064
function on_mouse_move(x, y) {
5065
	var btn = buttonsTraceMouse(x, y);
5066
	
5067
	if (btn != cur_btn) {
5068
		cur_btn && cur_btn.onMouseOut();
5069
		btn && btn.onMouseIn();
5070
	}
5071
	
5072
	cur_btn = btn;
5073
}
5074
5075
function on_mouse_lbtn_down(x, y) {
5076
	g_down = true;
5077
	btn_down = cur_btn;
5078
5079
	if (cur_btn) {
5080
		cur_btn.changeState(ButtonStates.down);
5081
	}
5082
}
5083
5084
function on_mouse_lbtn_up(x, y) {
5085
	if (cur_btn) {
5086
		cur_btn.changeState(ButtonStates.hover);
5087
		if( btn_down == cur_btn )
5088
			cur_btn.onClick(x, y);
5089
	}
5090
	g_down = false;
5091
}
5092
5093
function on_mouse_leave() {
5094
	if (cur_btn) {
5095
		cur_btn.changeState(ButtonStates.normal);
5096
	}
5097
}
5098
5099
function on_size() {
5100
	ww = window.Width;
5101
	wh = window.Height;
5102
    window.Repaint();
5103
}
5104
5105
function on_paint(gr) {
5106
	/*switch(window.GetProperty("mode", 1)) {
5107
		case 1:
5108
			//col = window.GetColorDUI(1);
5109
			break;
5110
		case 2:
5111
			col = utils.GetSysColor(4);
5112
			break;
5113
		case 3:
5114
			col = custom;
5115
			break;
5116
	}*/
5117
	//gr.FillSolidRect(0, 0, ww, wh, col);
5118
	buttonsDraw(gr);
5119
	//gr.DrawRect(0,0, ww, wh, 1.0, -6250336);
5120
}
5121
5122
function RGB(r,g,b) {
5123
	return (0xff000000|(r<<16)|(g<<8)|(b)); 
5124
}
5125
5126
function on_colors_changed() {
5127
    window.Repaint();
5128
}
5129
5130
5131
//init Buttons
5132
5133
//custom colour accessed through the context menu
5134
var custom = RGB(255,255,255);
5135
5136
//button width
5137
var bw = 24;
5138
//button height
5139
var bh = 20;
5140
5141
//Button position
5142
var top_margin = -1;
5143
var left_margin = 0;
5144
5145
var image_path0 = window.GetProperty("Button Path", fb.ProfilePath + "image");
5146
var image_path = (image_path0 + "\\");
5147
5148
//these 2 lines of code lock the panel size. you can comment them out or change the dimensions to suit
5149
//window.MinWidth = window.MaxWidth = 24;
5150
//window.MinHeight = window.MaxHeight = 20;
5151
5152
5153
5154
Buttons = {
5155
	but1: new Button(left_margin,top_margin,bw,bh, {normal: image_path + "youtube0.png", hover: image_path + "youtube1.png"}, function(){
5156
        //if (p.artist.indexOf("3dydfy://")== 0 | p.artist.indexOf("www.youtube.com/")== 0 | p.artist.indexOf("youtube.com/")== 0 | p.artist.indexOf("http://www.youtube.com/")== 0)
5157
        p.rbtn_up(24, 17);
5158
        //im.downloadONE();
5159
        /*else
5160
        {
5161
        p.artist = p.eval("%artist% %title%");
5162
        p.browser("http://www.youtube.com/results?search_query=" + encodeURIComponent(p.artist) + "&ie=utf-8");
5163
    }*/
5164
        }, "Youtube")
5165
	
5166
}
5167
5168
//fb.RunMainMenuCommand("Library/Search");
5169
//fb.RunContextCommand("Open containing folder");
5170
5171
function on_mouse_rbtn_up(x, y) {
5172
return true;
5173
}