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