1 /*
2  * Project: VizKit
3  * Version: 2.3
4 
5  * Date: 20090823
6  * File: VisualDataStore.cpp
7  *
8  */
9 
10 /***************************************************************************
11 
12 Copyright (c) 2004-2009 Heiko Wichmann (http://www.imagomat.de/vizkit)
13 
14 
15 This software is provided 'as-is', without any expressed or implied warranty.
16 In no event will the authors be held liable for any damages
17 arising from the use of this software.
18 
19 Permission is granted to anyone to use this software for any purpose,
20 including commercial applications, and to alter it and redistribute it
21 freely, subject to the following restrictions:
22 
23 1. The origin of this software must not be misrepresented;
24    you must not claim that you wrote the original software.
25    If you use this software in a product, an acknowledgment
26    in the product documentation would be appreciated
27    but is not required.
28 
29 2. Altered source versions must be plainly marked as such,
30    and must not be misrepresented as being the original software.
31 
32 3. This notice may not be removed or altered from any source distribution.
33 
34  ***************************************************************************/
35 
36 #include "VisualDataStore.h"
37 #include "VisualHostCommunication.h"
38 #include "VisualErrorHandling.h"
39 #include "VisualAudioLab.h"
40 #include "VisualConfiguration.h"
41 #include "VisualPreferences.h"
42 #include "VisualThreading.h"
43 #include "VisualNotification.h"
44 #include "VisualString.h"
45 #include "VisualFile.h"
46 #include "VisualStyledString.h"
47 #include "VisualImage.h"
48 #include "VisualPlayerState.h"
49 #include "VisualQuickTime.h"
50 
51 #if TARGET_OS_MAC
52 #include "VisualAppleScript.h"
53 #endif
54 #if TARGET_OS_MAC
55 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacMemory.h> // HUnlock
56 #endif
57 
58 
59 #if TARGET_OS_WIN
60 #include "iTunesCOMInterface.h"
61 #endif
62 
63 
64 using namespace VizKit;
65 
66 
67 const size_t VisualDataStore::audioMetaDataHistoryCount = 2;
68 
69 bool VisualDataStore::lyricsCreationThreadIsRunning = false;
70 
71 VisualDataStore* VisualDataStore::theVisualDataStore = NULL;  // singleton
72 
73 
74 const VisualItemIdentifier VisualDataStore::albumCoverArtworkImageId;
75 VisualItemIdentifier VisualDataStore::fileWithLyricsStringId;
76 VisualItemIdentifier VisualDataStore::trackIdentifierOfLyricsMetadata;
77 const VisualItemIdentifier VisualDataStore::styledTrackInfoStringId;
78 const VisualItemIdentifier VisualDataStore::styledTrackLyricsStringId;
79 const VisualItemIdentifier VisualDataStore::updateInformationStringId;
80 
81 
VisualDataStore()82 VisualDataStore::VisualDataStore() {
83 	VisualAudioMetaData emptyVisualAudioMetaData;
84     for (uint8 i = 0; i < audioMetaDataHistoryCount; i++) {
85 		audioMetaDataHistory.push_back(emptyVisualAudioMetaData);
86     }
87 	currAudioMetaDataHistoryIdx = audioMetaDataHistoryCount - 1;
88 	appVersionMajorNum = 0;
89 	appVersionMinorNum = 0;
90 }
91 
92 
~VisualDataStore()93 VisualDataStore::~VisualDataStore() {
94 
95 	processInfoMap.clear();
96 
97 	audioMetaDataHistory.clear();
98 }
99 
100 
getInstance()101 VisualDataStore* VisualDataStore::getInstance() {
102     if (theVisualDataStore == NULL) {
103 		theVisualDataStore = new VisualDataStore;
104     }
105 	return theVisualDataStore;
106 }
107 
108 
dispose()109 void VisualDataStore::dispose() {
110 	if (theVisualDataStore != NULL) {
111 		delete theVisualDataStore;
112 		theVisualDataStore = NULL;
113 	}
114 }
115 
116 
setValue(const ValueKey anIdentifier,const int anIntValue)117 void VisualDataStore::setValue(const ValueKey anIdentifier, const int anIntValue) {
118 	bool found = false;
119 
120 	theVisualDataStore = VisualDataStore::getInstance();
121 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
122 		if ((*it)->key == anIdentifier && (*it)->dataType == kIntPrefType) {
123 			(*it)->valueInt = anIntValue;
124 			found = true;
125 		}
126 	}
127 	if (found == false) {
128 		Value* aValue = new Value;
129 		aValue->dataType = kIntPrefType;
130 		aValue->key = anIdentifier;
131 		aValue->valueInt = anIntValue;
132 		strcpy(aValue->valueChar, "\0");
133 		aValue->valueBool = false;
134 		theVisualDataStore->valueVector.push_back(aValue);
135 	}
136 }
137 
138 
setValue(const ValueKey anIdentifier,const float aFloatValue)139 void VisualDataStore::setValue(const ValueKey anIdentifier, const float aFloatValue) {
140 	bool found = false;
141 
142 	theVisualDataStore = VisualDataStore::getInstance();
143 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
144 		if ((*it)->key == anIdentifier && (*it)->dataType == kFloatPrefType) {
145 			(*it)->valueFloat = aFloatValue;
146 			found = true;
147 		}
148 	}
149 	if (found == false) {
150 		Value* aValue = new Value;
151 		aValue->dataType = kFloatPrefType;
152 		aValue->key = anIdentifier;
153 		aValue->valueFloat = aFloatValue;
154 		aValue->valueInt = 0;
155 		strcpy(aValue->valueChar, "\0");
156 		aValue->valueBool = false;
157 		theVisualDataStore->valueVector.push_back(aValue);
158 	}
159 }
160 
161 
setValue(const ValueKey anIdentifier,const char * const aCharValue)162 void VisualDataStore::setValue(const ValueKey anIdentifier, const char* const aCharValue) {
163 	bool found = false;
164 
165 	char errStr[256] = "\0";
166 	if (strlen(aCharValue) > 255) {
167 		strncat(errStr, aCharValue, 255);
168 		writeLog("char value too long");
169 		return;
170 	}
171 
172 	theVisualDataStore = VisualDataStore::getInstance();
173 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
174 		if ((*it)->key == anIdentifier && (*it)->dataType == kCharPrefType) {
175 			strcpy((*it)->valueChar, aCharValue);
176 			found = true;
177 		}
178 	}
179 	if (found == false) {
180 		Value* aValue = new Value;
181 		aValue->dataType = kCharPrefType;
182 		aValue->key = anIdentifier;
183 		strcpy(aValue->valueChar, aCharValue);
184 		aValue->valueInt = 0;
185 		aValue->valueBool = false;
186 		theVisualDataStore->valueVector.push_back(aValue);
187 	}
188 }
189 
190 
setValue(const ValueKey anIdentifier,const bool aBoolValue)191 void VisualDataStore::setValue(const ValueKey anIdentifier, const bool aBoolValue) {
192 	bool found = false;
193 	theVisualDataStore = VisualDataStore::getInstance();
194 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
195 		if ((*it)->key == anIdentifier && (*it)->dataType == kBoolPrefType) {
196 			(*it)->valueBool = aBoolValue;
197 			found = true;
198 		}
199 	}
200 	if (found == false) {
201 		Value* aValue = new Value;
202 		aValue->dataType = kBoolPrefType;
203 		aValue->key = anIdentifier;
204 		aValue->valueBool = aBoolValue;
205 		aValue->valueInt = 0;
206 		aValue->valueFloat = 0.0f;
207 		strcpy(aValue->valueChar, "\0");
208 		theVisualDataStore->valueVector.push_back(aValue);
209 	}
210 }
211 
212 
getValueInt(const ValueKey anIdentifier,bool * wasSet)213 int VisualDataStore::getValueInt(const ValueKey anIdentifier, bool* wasSet) {
214 
215 	int prefVal = 0;
216 
217 	if (wasSet != NULL) {
218 		*wasSet = false;
219 	}
220 
221 	theVisualDataStore = VisualDataStore::getInstance();
222 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
223 		if ((*it)->key == anIdentifier && (*it)->dataType == kIntPrefType) {
224 			if (wasSet != NULL) {
225 				*wasSet = true;
226 			}
227 			return (*it)->valueInt;
228 		}
229 	}
230 
231 	return prefVal;
232 }
233 
234 
getValueFloat(const ValueKey anIdentifier,bool * wasSet)235 float VisualDataStore::getValueFloat(const ValueKey anIdentifier, bool* wasSet) {
236 
237 	float prefVal = 0;
238 
239 	if (wasSet != NULL) {
240 		*wasSet = false;
241 	}
242 
243 	theVisualDataStore = VisualDataStore::getInstance();
244 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
245 		if ((*it)->key == anIdentifier && (*it)->dataType == kFloatPrefType) {
246 			if (wasSet != NULL) {
247 				*wasSet = true;
248 			}
249 			return (*it)->valueFloat;
250 		}
251 	}
252 
253 	return prefVal;
254 }
255 
256 
getValueChar(const ValueKey anIdentifier,char * outPrefVal,bool * wasSet)257 void VisualDataStore::getValueChar(const ValueKey anIdentifier, char* outPrefVal, bool* wasSet) {
258 
259 	strcpy(outPrefVal, "\0");
260 
261 	if (wasSet != NULL) {
262 		*wasSet = false;
263 	}
264 
265 	theVisualDataStore = VisualDataStore::getInstance();
266 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
267 		if ((*it)->key == anIdentifier && (*it)->dataType == kCharPrefType) {
268 			if (wasSet != NULL) {
269 				*wasSet = true;
270 			}
271 			strncat(outPrefVal, (*it)->valueChar, strlen((*it)->valueChar));
272 			return;
273 		}
274 	}
275 
276 }
277 
278 
getValueBool(const ValueKey anIdentifier,bool * wasSet)279 bool VisualDataStore::getValueBool(const ValueKey anIdentifier, bool* wasSet) {
280 
281 	bool prefVal = false;
282 
283 	if (wasSet != NULL) {
284 		*wasSet = false;
285 	}
286 
287 	theVisualDataStore = VisualDataStore::getInstance();
288 	for (ValueVectorIterator it = theVisualDataStore->valueVector.begin(); it != theVisualDataStore->valueVector.end(); it++) {
289 		if ((*it)->key == anIdentifier && (*it)->dataType == kBoolPrefType) {
290 			if (wasSet != NULL) {
291 				*wasSet = true;
292 			}
293 			return (*it)->valueBool;
294 		}
295 	}
296 
297 	return prefVal;
298 }
299 
300 
setAppVersionNum(uint8 majorVersionNum,uint8 minorVersionNum)301 void VisualDataStore::setAppVersionNum(uint8 majorVersionNum, uint8 minorVersionNum) {
302 	theVisualDataStore = VisualDataStore::getInstance();
303 	theVisualDataStore->appVersionMajorNum = majorVersionNum;
304 	theVisualDataStore->appVersionMinorNum = minorVersionNum;
305 }
306 
307 
getAppVersionMajorNum()308 uint8 VisualDataStore::getAppVersionMajorNum() {
309 	theVisualDataStore = VisualDataStore::getInstance();
310 	return theVisualDataStore->appVersionMajorNum;
311 }
312 
313 
getAppVersionMinorNum()314 uint8 VisualDataStore::getAppVersionMinorNum() {
315 	theVisualDataStore = VisualDataStore::getInstance();
316 	return theVisualDataStore->appVersionMinorNum;
317 }
318 
319 
resetCurrAudioMetaData(void)320 void VisualDataStore::resetCurrAudioMetaData(void) {
321 	theVisualDataStore = VisualDataStore::getInstance();
322 	theVisualDataStore->currAudioMetaData.init();
323 }
324 
325 
setAudioTrackName(const uint16 * const audioTrackName,uint32 audioTrackNameLength)326 void VisualDataStore::setAudioTrackName(const uint16* const audioTrackName, uint32 audioTrackNameLength) {
327 	theVisualDataStore = VisualDataStore::getInstance();
328 	VisualString trackName(audioTrackName, audioTrackNameLength);
329 	theVisualDataStore->currAudioMetaData.setTrackName(trackName);
330 }
331 
332 
setAudioTrackArtistName(const uint16 * const audioTrackArtistName,uint32 audioTrackArtistNameLength)333 void VisualDataStore::setAudioTrackArtistName(const uint16* const audioTrackArtistName, uint32 audioTrackArtistNameLength) {
334 	theVisualDataStore = VisualDataStore::getInstance();
335 	VisualString trackArtistName(audioTrackArtistName, audioTrackArtistNameLength);
336 	theVisualDataStore->currAudioMetaData.setTrackArtist(trackArtistName);
337 }
338 
339 
setAudioTrackAlbumName(const uint16 * const audioTrackAlbumName,uint32 audioTrackAlbumNameLength)340 void VisualDataStore::setAudioTrackAlbumName(const uint16* const audioTrackAlbumName, uint32 audioTrackAlbumNameLength) {
341 	theVisualDataStore = VisualDataStore::getInstance();
342 	VisualString trackAlbumName(audioTrackAlbumName, audioTrackAlbumNameLength);
343 	theVisualDataStore->currAudioMetaData.setTrackAlbum(trackAlbumName);
344 }
345 
346 
setAudioTrackComposer(const uint16 * const audioTrackComposer,uint32 audioTrackComposerLength)347 void VisualDataStore::setAudioTrackComposer(const uint16* const audioTrackComposer, uint32 audioTrackComposerLength) {
348 	theVisualDataStore = VisualDataStore::getInstance();
349 	VisualString trackComposer(audioTrackComposer, audioTrackComposerLength);
350 	theVisualDataStore->currAudioMetaData.setTrackComposer(trackComposer);
351 }
352 
353 
setAudioStreamTitle(const char * const audioStreamTitle,uint32 audioStreamTitleLength)354 void VisualDataStore::setAudioStreamTitle(const char* const audioStreamTitle, uint32 audioStreamTitleLength) {
355 	theVisualDataStore = VisualDataStore::getInstance();
356 	VisualString streamTitle(audioStreamTitle, audioStreamTitleLength);
357 	theVisualDataStore->currAudioMetaData.setStreamTitle(streamTitle);
358 }
359 
360 
setAudioStreamTitle(const uint16 * const audioStreamTitle,uint32 audioStreamTitleLength)361 void VisualDataStore::setAudioStreamTitle(const uint16* const audioStreamTitle, uint32 audioStreamTitleLength) {
362 	theVisualDataStore = VisualDataStore::getInstance();
363 	VisualString streamTitle(audioStreamTitle, audioStreamTitleLength);
364 	theVisualDataStore->currAudioMetaData.setStreamTitle(streamTitle);
365 }
366 
367 
setAudioStreamMessage(const char * const audioStreamMessage,uint32 audioStreamMessageLength)368 void VisualDataStore::setAudioStreamMessage(const char* const audioStreamMessage, uint32 audioStreamMessageLength) {
369 	theVisualDataStore = VisualDataStore::getInstance();
370 	VisualString streamMessage(audioStreamMessage, audioStreamMessageLength);
371 	theVisualDataStore->currAudioMetaData.setStreamMessage(streamMessage);
372 }
373 
374 
setAudioStreamMessage(const uint16 * const audioStreamMessage,uint32 audioStreamMessageLength)375 void VisualDataStore::setAudioStreamMessage(const uint16* const audioStreamMessage, uint32 audioStreamMessageLength) {
376 	theVisualDataStore = VisualDataStore::getInstance();
377 	VisualString streamMessage(audioStreamMessage, audioStreamMessageLength);
378 	theVisualDataStore->currAudioMetaData.setStreamMessage(streamMessage);
379 }
380 
381 
setAudioStreamURL(const char * const audioStreamURL,uint32 audioStreamURLLength)382 void VisualDataStore::setAudioStreamURL(const char* const audioStreamURL, uint32 audioStreamURLLength) {
383 	theVisualDataStore = VisualDataStore::getInstance();
384 	VisualString streamURL(audioStreamURL, audioStreamURLLength);
385 	theVisualDataStore->currAudioMetaData.setStreamURL(streamURL);
386 }
387 
388 
setAudioStreamURL(const uint16 * const audioStreamURL,uint32 audioStreamURLLength)389 void VisualDataStore::setAudioStreamURL(const uint16* const audioStreamURL, uint32 audioStreamURLLength) {
390 	theVisualDataStore = VisualDataStore::getInstance();
391 	VisualString streamURL(audioStreamURL, audioStreamURLLength);
392 	theVisualDataStore->currAudioMetaData.setStreamURL(streamURL);
393 }
394 
395 
setAudioTrackSizeInBytes(int sizeInBytes)396 void VisualDataStore::setAudioTrackSizeInBytes(int sizeInBytes) {
397 	theVisualDataStore = VisualDataStore::getInstance();
398 	theVisualDataStore->currAudioMetaData.setTrackSizeInBytes(sizeInBytes);
399 }
400 
401 
setAudioTrackYear(uint16 aYear)402 void VisualDataStore::setAudioTrackYear(uint16 aYear) {
403 	theVisualDataStore = VisualDataStore::getInstance();
404 	theVisualDataStore->currAudioMetaData.setYear(aYear);
405 }
406 
407 
setAudioDataIsStream(bool isStream)408 void VisualDataStore::setAudioDataIsStream(bool isStream) {
409 	theVisualDataStore = VisualDataStore::getInstance();
410 	theVisualDataStore->currAudioMetaData.setIsStream(isStream);
411 }
412 
413 
setLyricsOfCurrentTrack(const VisualString & lyricsString)414 void VisualDataStore::setLyricsOfCurrentTrack(const VisualString& lyricsString) {
415 	theVisualDataStore = VisualDataStore::getInstance();
416 
417 	/*
418 	VisualFile aFile;
419 	aFile.initWithUserDesktopDirectory();
420 	VisualString fileName;
421 	fileName.initWithUTF8Buffer("lyricsTest.txt", 15);
422 	aFile.appendFileName(fileName);
423 	const uint16* const data = lyricsString.clone()->getUtf16Representation();
424 	uint32 length = lyricsString.getNumberOfCharacters();
425 	VisualFile::writeDataToFile((void**)&data, length * sizeof(uint16), aFile);
426 	 */
427 
428 	VisualString* normalizedLyrics = lyricsString.clone();
429 	if (normalizedLyrics) {
430 		normalizedLyrics->normalizeLineEndings();
431 		theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].setTrackLyrics(*normalizedLyrics);
432 		delete normalizedLyrics;
433 	}
434 }
435 
436 
analyzeCurrentlySetMetadata()437 bool VisualDataStore::analyzeCurrentlySetMetadata() {
438 	bool audioTrackDidChange = false;
439 	theVisualDataStore = VisualDataStore::getInstance();
440 	if (theVisualDataStore->currAudioMetaData != theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx]) {
441 		theVisualDataStore->advanceAudioMetaDataHistory();
442 		theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx] = theVisualDataStore->currAudioMetaData;
443 		audioTrackDidChange = true;
444 	}
445 	return audioTrackDidChange;
446 }
447 
448 
advanceAudioMetaDataHistory()449 void VisualDataStore::advanceAudioMetaDataHistory() {
450 	if ((this->currAudioMetaDataHistoryIdx + 1) >= this->audioMetaDataHistory.size()) {
451 		this->currAudioMetaDataHistoryIdx = 0;
452 	} else {
453 		this->currAudioMetaDataHistoryIdx++;
454 	}
455 }
456 
457 
getInfoOfCurrentAudioDataForDisplay()458 VisualString VisualDataStore::getInfoOfCurrentAudioDataForDisplay() {
459 	VisualString displayInfo;
460 	if (VisualDataStore::currentlyPlayingAudioIsStream()) {
461 		const VisualString& streamTitle = theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getStreamTitle();
462 		const VisualString& streamMessage = theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getStreamMessage();
463 		if (!streamTitle.isEmpty()) {
464 			displayInfo = streamTitle;
465 		} else if (!streamMessage.isEmpty()) {
466 			displayInfo = streamMessage;
467 		}
468 	} else {
469 		const VisualString& trackArtist = theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackArtist();
470 		if (!trackArtist.isEmpty()) {
471 			displayInfo = trackArtist;
472 		}
473 		const VisualString& trackName = theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackName();
474 		if (!trackName.isEmpty()) {
475 			if (!displayInfo.isEmpty()) {
476 				char trackInfoDisplayItemsDelimiterCharacters[32];
477 				VisualPreferences::getValue(VisualPreferences::kTrackInfoDisplayItemsDelimiterCharacters, trackInfoDisplayItemsDelimiterCharacters);
478 				displayInfo = (displayInfo + trackInfoDisplayItemsDelimiterCharacters);
479 			}
480 			displayInfo = (displayInfo + trackName);
481 		}
482 	}
483 	return displayInfo;
484 }
485 
486 
getTrackSizeInBytes()487 uint32 VisualDataStore::getTrackSizeInBytes() {
488 	theVisualDataStore = VisualDataStore::getInstance();
489 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackSizeInBytes();
490 }
491 
492 
getTrackYear()493 uint16 VisualDataStore::getTrackYear() {
494 	theVisualDataStore = VisualDataStore::getInstance();
495 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getYear();
496 }
497 
498 
getNameOfCurrentTrack()499 VisualString VisualDataStore::getNameOfCurrentTrack() {
500 	theVisualDataStore = VisualDataStore::getInstance();
501 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackName();
502 }
503 
504 
getArtistOfCurrentTrack()505 VisualString VisualDataStore::getArtistOfCurrentTrack() {
506 	theVisualDataStore = VisualDataStore::getInstance();
507 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackArtist();
508 }
509 
510 
getAlbumOfCurrentTrack()511 VisualString VisualDataStore::getAlbumOfCurrentTrack() {
512 	theVisualDataStore = VisualDataStore::getInstance();
513 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackAlbum();
514 }
515 
516 
getLyricsOfCurrentTrack()517 VisualString VisualDataStore::getLyricsOfCurrentTrack() {
518 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackLyrics();
519 }
520 
521 
getIdentifierOfCurrentTrack()522 VisualItemIdentifier VisualDataStore::getIdentifierOfCurrentTrack() {
523 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getTrackIdentifier();
524 }
525 
526 
currentlyPlayingAudioIsStream(void)527 bool VisualDataStore::currentlyPlayingAudioIsStream(void) {
528 	return theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].getIsStream();
529 }
530 
531 
setProcessInfo(const char * const labelStr,const char * const valueStr)532 void VisualDataStore::setProcessInfo(const char* const labelStr, const char* const valueStr) {
533 	std::string labelString(labelStr);
534 	std::string valueString(valueStr);
535 	ProcessInfoMapIterator it;
536 	theVisualDataStore = VisualDataStore::getInstance();
537 	it = theVisualDataStore->processInfoMap.find(labelString);
538 	if (it == theVisualDataStore->processInfoMap.end()) {
539 		theVisualDataStore->processInfoMap[labelString] = valueString;
540 	} else {
541 		it->second = valueString;
542 	}
543 }
544 
545 
getProcessInfoMap()546 const std::map<std::string, std::string>* const VisualDataStore::getProcessInfoMap() {
547 	theVisualDataStore = VisualDataStore::getInstance();
548 	return &theVisualDataStore->processInfoMap;
549 }
550 
551 
createCoverArtImage()552 VisualImage* VisualDataStore::createCoverArtImage() {
553 
554 	size_t numberOfBytes = 0;
555 	uint16 numberOfArtworks = 0;
556 	void* albumCoverArtworkImageData = NULL;
557 
558 	numberOfArtworks = VisualHostCommunication::getCurrentTrackCoverArt(&albumCoverArtworkImageData, (uint32&)numberOfBytes);
559 
560 	if (numberOfArtworks == 0) return NULL;
561 
562 	VisualImage* anImage = new VisualImage;
563 	const char* coverArtDataPtr = (const char*)albumCoverArtworkImageData;
564 	bool success = anImage->initWithEncodedData(coverArtDataPtr, numberOfBytes);
565 
566 	VisualHostCommunication::dispose();
567 
568 	if (!success) {
569 		return NULL;
570 	} else if (anImage->isEmpty()) {
571 		delete anImage;
572 		return NULL;
573 	}
574 
575 	return anImage;
576 }
577 
578 
createLyricsOfCurrentTrack()579 bool VisualDataStore::createLyricsOfCurrentTrack() {
580 	bool success = false;
581 	if (VisualDataStore::lyricsCreationThreadIsRunning == true) return false;
582 	success = VisualThreading::createThread((ThreadingFuncPtr)VisualDataStore::writeLyricsToFile);
583 	return success;
584 }
585 
586 
587 #if TARGET_OS_MAC
writeLyricsToFile(void * parameter)588 OSStatus VisualDataStore::writeLyricsToFile(void* parameter) {
589 
590 	bool success = true;
591 
592 	VisualDataStore::lyricsCreationThreadIsRunning = true;
593 
594 	VisualItemIdentifier currTrackId = VisualDataStore::getIdentifierOfCurrentTrack();
595 	VisualDataStore::trackIdentifierOfLyricsMetadata = currTrackId;
596 
597 	bool debug = false;
598 
599 	if (debug == true) {
600 		writeLog("writeLyricsToFile (begin)");
601 	}
602 
603 	VisualPlayerState* theVisualPlayerState = VisualPlayerState::getInstance();
604 
605 	VisualString tempFileName = VisualString("VizKitLyrics.tmp.txt");
606 	VisualFile tempFile;
607 	success = tempFile.initWithDirectoryOfTemporaryItems();
608 	if (!success) {
609 		return (OSStatus)1001;
610 	}
611 	success = tempFile.appendFileName(tempFileName);
612 	if (!success) {
613 		return (OSStatus)1002;
614 	}
615 
616 	if ((theVisualPlayerState->getPlayerShowMode() & kIsShowing) != kIsShowing) {
617 		return (OSStatus)1003;
618 	}
619 
620 	VisualFile appleScriptFile;
621 	success = appleScriptFile.initWithResourcesDirectory();
622 	if (!success) {
623 		return (OSStatus)1004;
624 	}
625 	VisualString appleScriptFileName = VisualString("getLyrics.applescript");
626 	success = appleScriptFile.appendFileName(appleScriptFileName);
627 	if (!success) {
628 		return (OSStatus)1005;
629 	}
630 
631 	if (debug == true) {
632 		VisualString appleScriptFilePath;
633 		appleScriptFile.getFilePath(appleScriptFilePath);
634 		VisualString tempFilePath;
635 		tempFile.getFilePath(tempFilePath);
636 		char logStr[256];
637 		sprintf(logStr, "before executeScriptFile(), %s %s", appleScriptFilePath.getUtf8Representation(), tempFilePath.getUtf8Representation());
638 		writeLog(logStr);
639 	}
640 
641 	VisualAppleScript::executeScriptFile(appleScriptFile);
642 
643 	if (debug == true) {
644 		writeLog("after executeScriptFile()");
645 	}
646 
647 	VisualNotification lyricsAreWrittenIntoTempFileNotification;
648 	lyricsAreWrittenIntoTempFileNotification.setKey(kLyricsAreWrittenIntoTempFileMsg);
649 	lyricsAreWrittenIntoTempFileNotification.setObject(tempFile);
650 	lyricsAreWrittenIntoTempFileNotification.post();
651 
652 	if (debug == true) {
653 		writeLog("---------------------- writeLyricsToFile (end)");
654 	}
655 
656 	VisualDataStore::lyricsCreationThreadIsRunning = false;
657 
658 	return noErr;
659 }
660 
661 #endif
662 
663 #if TARGET_OS_WIN
writeLyricsToFile(LPVOID lpParam)664 DWORD WINAPI VisualDataStore::writeLyricsToFile(LPVOID lpParam) {
665 
666 	VisualDataStore::lyricsCreationThreadIsRunning = true;
667 
668 	DWORD retVal = 0;
669 
670 	IiTunes* iITunes = 0;
671 	IITTrack* iITrack = 0;
672 
673 	CoInitialize(0);
674 	//HRESULT result = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
675 
676 	try
677 	{
678 		HRESULT hRes = ::CoCreateInstance(CLSID_iTunesApp, NULL, CLSCTX_LOCAL_SERVER, IID_IiTunes, (PVOID *)&iITunes);
679 
680 		if(hRes == S_OK && iITunes) {
681 			iITunes->get_CurrentTrack(&iITrack);
682 			if(iITrack) {
683 
684 				BSTR bstrTrack = 0;
685 
686 				iITrack->get_Name((BSTR *)&bstrTrack);
687 
688 				BSTR bstrLyricsTrack = ::SysAllocString((const OLECHAR*)(""));
689 				//BSTR bstrLyricsTrack = 0;
690 				IITFileOrCDTrack* iTrackFile;
691 				iITrack->QueryInterface(IID_IITFileOrCDTrack, (void **)&iTrackFile);
692 				if (iTrackFile) {
693 					iTrackFile->get_Lyrics(&bstrLyricsTrack);
694 				}
695 				theVisualDataStore = VisualDataStore::getInstance();
696 
697 				uint16 trackLyricsStringLength = lstrlenW(bstrLyricsTrack);
698 				VisualString lyrics((uint16*)bstrLyricsTrack, trackLyricsStringLength);
699 				VisualDataStore::setLyricsOfCurrentTrack(lyrics);
700 				//theVisualDataStore->audioMetaDataHistory[theVisualDataStore->currAudioMetaDataHistoryIdx].setTrackLyrics(lyrics);
701 				//dynamic_cast<IITFileOrCDTrack*>(iITrack)->get_Lyrics((BSTR *)&bstrLyricsTrack);
702 				//dynamic_cast<IITFileOrCDTrack*>(iITrack)->get_Lyrics((BSTR *)&theVisualDataStore->trackLyrics);
703 
704 			}
705 		}
706 
707 		iITunes->Release();
708 
709 	}
710 	catch(...)
711 	{
712 		try
713 		{
714 			if(iITunes)
715 				iITunes->Release();
716 
717 			if(iITrack)
718 				iITrack->Release();
719 		}
720 		catch(...)
721 		{
722 		}
723 	}
724 
725 	CoUninitialize();
726 
727 
728 /*
729 	iTunesLib.iTunesAppClass itl = new iTunesLib.iTunesAppClass();
730 	string currTrack = itl.CurrentTrack.Name.ToString();
731 	iTunesLib.IITTrack myTrack = (iTunesLib.IITTrack)itl.CurrentTrack;
732 	iTunesLib.IITFileOrCDTrack test = (iTunesLib.IITFileOrCDTrack)myTrack;
733 	string myLyrics = test.Lyrics;
734 
735 	MessageBox.Show("Track: "+currTrack+", Lyrics: "+myLyrics);
736 */
737 
738 	VisualNotification::post(kLyricsAreAvailableInMetadataMsg);
739 
740 	VisualDataStore::lyricsCreationThreadIsRunning = false;
741 
742 	return retVal;
743 }
744 #endif
745 
746 
747 
748 #if TARGET_OS_MAC
readFileAndSendNotificationWithString(void * fileWithStringContent)749 OSStatus VisualDataStore::readFileAndSendNotificationWithString(void* fileWithStringContent) {
750 	OSStatus retVal = noErr;
751 #endif
752 #if TARGET_OS_WIN
753 DWORD VisualDataStore::readFileAndSendNotificationWithString(LPVOID fileWithStringContent) {
754 	DWORD retVal = 0;
755 #endif
756 
757 	bool debug = false;
758 
759 	if (debug == true) {
760 		writeLog("readFileAndSendNotificationWithString (start)");
761 	}
762 
763 	VisualFile* visualFile = reinterpret_cast<VisualFile*>(fileWithStringContent);
764 
765 	VisualString stringContentsOfFile;
766 	stringContentsOfFile.initWithContentsOfFile(*visualFile);
767 
768 	if (debug == true) {
769 		writeLog("after stringContentsOfFile.initWithContentsOfFile()");
770 	}
771 	if (stringContentsOfFile.getNumberOfCharacters() == 0) {
772 		if (debug == true) {
773 			writeLog("stringContentsOfFile.getNumberOfCharacters() == 0");
774 		}
775 #if TARGET_OS_MAC
776 		retVal = (OSStatus)1001;
777 #endif
778 #if TARGET_OS_WIN
779 		retVal = (DWORD)1001;
780 #endif
781 		return retVal;
782 	}
783 
784 	VisualNotification aNotification(visualFile->getIdentifier());
785 	aNotification.setKey(kStringWithIdentifierLoadedAndCreatedMsg);
786 	aNotification.setObject(stringContentsOfFile);
787 
788 	delete visualFile;
789 	visualFile = NULL;
790 
791 	aNotification.post();
792 
793 	if (debug == true) {
794 		writeLog("readFileAndSendNotificationWithString (end)");
795 	}
796 
797 	return retVal;
798 }
799 
800 
801 #if TARGET_OS_MAC
802 OSStatus VisualDataStore::readFileAndRemoveFileAndSendNotificationWithString(void* fileWithStringContent) {
803 	OSStatus retVal = noErr;
804 #endif
805 #if TARGET_OS_WIN
806 DWORD VisualDataStore::readFileAndRemoveFileAndSendNotificationWithString(LPVOID fileWithStringContent) {
807 	DWORD retVal = 0;
808 #endif
809 
810 	bool debug = false;
811 
812 	if (debug == true) {
813 		writeLog("readFileAndRemoveFileAndSendNotificationWithString (start)");
814 	}
815 
816 	VisualFile* visualFile = reinterpret_cast<VisualFile*>(fileWithStringContent);
817 
818 	if (!visualFile) {
819 #if TARGET_OS_MAC
820 		retVal = (OSStatus)1001;
821 #endif
822 #if TARGET_OS_WIN
823 		retVal = (DWORD)1001;
824 #endif
825 		return retVal;
826 	}
827 
828 	VisualString stringContentsOfFile;
829 	stringContentsOfFile.initWithContentsOfFile(*visualFile);
830 
831 	if (debug == true) {
832 		writeLog("after stringContentsOfFile.initWithContentsOfFile()");
833 	}
834 	if (stringContentsOfFile.getNumberOfCharacters() == 0) {
835 		if (debug == true) {
836 			writeLog("stringContentsOfFile.getNumberOfCharacters() == 0");
837 		}
838 #if TARGET_OS_MAC
839 		retVal = (OSStatus)1002;
840 #endif
841 #if TARGET_OS_WIN
842 		retVal = (DWORD)1002;
843 #endif
844 		return retVal;
845 	}
846 
847 	VisualItemIdentifier fileIdentifier = visualFile->getIdentifier();
848 	VisualNotification aNotification(fileIdentifier);
849 	aNotification.setKey(kStringWithIdentifierLoadedAndCreatedMsg);
850 	aNotification.setObject(stringContentsOfFile);
851 
852 	bool success = visualFile->remove();
853 	if (debug == true) {
854 		writeLog("tempFile.remove()");
855 	}
856 	if (!success) {
857 		if (debug == true) {
858 			writeLog("no success after remove()");
859 		}
860 #if TARGET_OS_MAC
861 		retVal = (OSStatus)1003;
862 #endif
863 #if TARGET_OS_WIN
864 		retVal = (DWORD)1003;
865 #endif
866 	}
867 
868 	delete visualFile;
869 	visualFile = NULL;
870 
871 	aNotification.post();
872 
873 	if (debug == true) {
874 		writeLog("readFileAndRemoveFileAndSendNotificationWithString (end)");
875 	}
876 
877 	return retVal;
878 }
879