private AudioscrobblerResponse GetResponse_UNKNOWN(string responseString)
        {
            AudioscrobblerResponse response = new AudioscrobblerResponse();

            response.Type = AudioscrobblerResponseType.UNKNOWN;
            return(response);
        }
        /// <summary>
        /// Send a request to the audioscrobbler server
        /// parse the response into the approriate
        /// AudioscrobblerReponse type
        /// </summary>
        private AudioscrobblerResponse Send(string url)
        {
            // the response object to return
            AudioscrobblerResponse aResponse = null;

            // create the request
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            //request.Proxy = new WebProxy("proxy.inside.us.dell.com");
            //request.Proxy.Credentials = new NetworkCredential("Daniel_Poage", "Ahascsi2940u2w1");

            // set the method to POST
            request.Method        = "POST";
            request.ContentLength = 0;

            // grab the response
            // TODO: Change response type to HttpWebResponse
            // TODO: Better error handling
            using (WebResponse response = request.GetResponse())
            {
                using (Stream dataStream = response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(dataStream))
                    {
                        // parse the response string
                        aResponse = ParseResponse(reader.ReadToEnd());
                    }
                }
            }
            return(aResponse);
        }
        // establish the connection between the client and audioscrobbler
        private void Handshake()
        {
            // handshake url
            // {0} = clientid
            // {1} = client version
            // {2} = username
            string handshakeUrl = "http://post.audioscrobbler.com/?hs=true&p=1.1&c={0}&v={1}&u={2}";

            // values for client
            string clientid      = "tst";
            string clientversion = "1.0";

            // reset variables that are set during the handshake
            urlPrefix           = String.Empty;
            handshakeSuccessful = false;

            // generate the approriate handshake url
            handshakeUrl = string.Format(handshakeUrl, clientid, clientversion, username);

            // send the response
            AudioscrobblerResponse response = this.Send(handshakeUrl);

            // set the interval value returned by the response
            interval = response.Interval;

            // react based on the response type
            switch (response.Type)
            {
            // successful response: grab the url to send tracks to
            case AudioscrobblerResponseType.UPTODATE:
                urlPrefix           = GetUrlPrefix(response.Variables["MD5Challenge"], response.Variables["UrlToSubmitScript"]);
                handshakeSuccessful = true;
                break;

            // successful response: grab the url to send tracks to
            case AudioscrobblerResponseType.UPDATE:
                urlPrefix           = GetUrlPrefix(response.Variables["MD5Challenge"], response.Variables["UrlToSubmitScript"]);
                handshakeSuccessful = true;
                break;

            // invalid user
            case AudioscrobblerResponseType.BADUSER:
                throw new AudioscrobblerException("Invalid User");

            // request failed for some other reason
            case AudioscrobblerResponseType.FAILED:
                throw new AudioscrobblerException(response.Variables["Reason"]);
            }
        }
        /// <summary>
        /// Submits a list of tracks to audioscrobbler
        /// </summary>
        public void SubmitTrack(IList <IMediaItem> tracks, IList <DateTime> timesStarted)
        {
            // if there are no tracks in this request, return
            if (tracks.Count == 0 || tracks.Count != timesStarted.Count)
            {
                return;
            }

            // verify that a successful handshake has occured
            if (handshakeSuccessful == false)
            {
                this.Handshake();
            }

            // initialize the url to send requests to
            string url = urlPrefix;

            // loop through each track and append its info to the url
            for (int i = 0; i < tracks.Count; i++)
            {
                url += ProcessTrack(tracks[i], timesStarted[i], i);
            }

            // send the request
            AudioscrobblerResponse response = this.Send(url);

            // set the interval variable
            interval = response.Interval;

            // parse the response type
            // (doesn't do anything for now)
            switch (response.Type)
            {
            case AudioscrobblerResponseType.BADAUTH:
                break;

            case AudioscrobblerResponseType.FAILED:
                break;

            case AudioscrobblerResponseType.OK:
                break;
            }

            // update the date of the last request
            // (isn't used now, but could be used in conjunction
            // with interval to wait before submitting a request)
            lastRequest = DateTime.Now;
        }
        /// <summary>
        /// Parse the response string into the approriate type
        /// </summary>
        private AudioscrobblerResponse ParseResponse(string responseString)
        {
            // if for any reason the response is empty (why would it be?),
            // return null
            if (responseString.Length == 0)
            {
                return(null);
            }

            AudioscrobblerResponse response = new AudioscrobblerResponse();

            // figure out the response type and parse it approriately
            if (RequestStartsWith(responseString, "UPTODATE"))
            {
                response = GetResponse_UPTODATE(responseString);
            }
            else if (RequestStartsWith(responseString, "UPDATE"))
            {
                response = GetResponse_UPDATE(responseString);
            }
            else if (RequestStartsWith(responseString, "FAILED"))
            {
                response = GetResponse_FAILED(responseString);
            }
            else if (RequestStartsWith(responseString, "BADUSER"))
            {
                response = GetResponse_BADUSER(responseString);
            }
            else if (RequestStartsWith(responseString, "BADAUTH"))
            {
                response = GetResponse_BADAUTH(responseString);
            }
            else if (RequestStartsWith(responseString, "OK"))
            {
                response = GetResponse_OK(responseString);
            }
            else
            {
                response = GetResponse_UNKNOWN(responseString);
            }

            return(response);
        }
        private AudioscrobblerResponse GetResponse_OK(string responseString)
        {
            AudioscrobblerResponse response = new AudioscrobblerResponse();

            response.Type = AudioscrobblerResponseType.OK;

            string       regex   = @"OK\nINTERVAL (?<Interval>[0-9]*)";
            RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase;
            Regex        reg     = new Regex(regex, options);

            Match match = reg.Match(responseString);

            if (match.Success)
            {
                response.Interval = Convert.ToInt32(match.Groups["Interval"].Value);
            }

            return(response);
        }
        private AudioscrobblerResponse GetResponse_FAILED(string responseString)
        {
            AudioscrobblerResponse response = new AudioscrobblerResponse();

            response.Type = AudioscrobblerResponseType.FAILED;

            string       regex   = @"FAILED (?<Reason>[^\n]*)\nINTERVAL (?<Interval>[0-9]*)";
            RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase;
            Regex        reg     = new Regex(regex, options);

            Match match = reg.Match(responseString);

            if (match.Success)
            {
                response.Variables.Add("Reason", match.Groups["Reason"].Value);
                response.Interval = Convert.ToInt32(match.Groups["Interval"].Value);
            }

            return(response);
        }
        // All the response parsers below work the same way
        // Set the approriate AudioscrobblerResponseType
        // and then user a regular expression to parse out the interval
        // and the variables

        private AudioscrobblerResponse GetResponse_UPTODATE(string responseString)
        {
            AudioscrobblerResponse response = new AudioscrobblerResponse();

            response.Type = AudioscrobblerResponseType.UPTODATE;

            string       regex   = @"UPTODATE\n(?<MD5Challenge>[^\n]*)\n(?<UrlToSubmitScript>[^\n]*)\nINTERVAL (?<Interval>[0-9]*)";
            RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase;
            Regex        reg     = new Regex(regex, options);

            Match match = reg.Match(responseString);

            if (match.Success)
            {
                response.Variables.Add("MD5Challenge", match.Groups["MD5Challenge"].Value);
                response.Variables.Add("UrlToSubmitScript", match.Groups["UrlToSubmitScript"].Value);
                response.Interval = Convert.ToInt32(match.Groups["Interval"].Value);
            }

            return(response);
        }
		private AudioscrobblerResponse GetResponse_UNKNOWN(string responseString)
		{
			AudioscrobblerResponse response = new AudioscrobblerResponse();
			response.Type = AudioscrobblerResponseType.UNKNOWN;
			return response;
		}
		private AudioscrobblerResponse GetResponse_OK(string responseString)
		{
			AudioscrobblerResponse response = new AudioscrobblerResponse();
			response.Type = AudioscrobblerResponseType.OK;

			string regex = @"OK\nINTERVAL (?<Interval>[0-9]*)";
			RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase;
			Regex reg = new Regex(regex, options);

			Match match = reg.Match(responseString);
			if (match.Success)
			{
				response.Interval = Convert.ToInt32(match.Groups["Interval"].Value);
			}

			return response;
		}
		private AudioscrobblerResponse GetResponse_FAILED(string responseString)
		{
			AudioscrobblerResponse response = new AudioscrobblerResponse();
			response.Type = AudioscrobblerResponseType.FAILED;

			string regex = @"FAILED (?<Reason>[^\n]*)\nINTERVAL (?<Interval>[0-9]*)";
			RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase;
			Regex reg = new Regex(regex, options);

			Match match = reg.Match(responseString);
			if (match.Success)
			{
				response.Variables.Add("Reason", match.Groups["Reason"].Value);
				response.Interval = Convert.ToInt32(match.Groups["Interval"].Value);
			}

			return response;
		}
		private AudioscrobblerResponse GetResponse_UPDATE(string responseString)
		{
			AudioscrobblerResponse response = new AudioscrobblerResponse();
			response.Type = AudioscrobblerResponseType.UPDATE;

			string regex = @"UPDATE (?<UpdateUrl>[^\n]*)\n(?<MD5Challenge>[^\n]*)\n(?<UrlToSubmitScript>[^\n]*)\nINTERVAL (?<Interval>[0-9]*)";
			RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase;
			Regex reg = new Regex(regex, options);

			Match match = reg.Match(responseString);
			if (match.Success)
			{
				response.Variables.Add("UpdateUrl", match.Groups["UpdateUrl"].Value);
				response.Variables.Add("MD5Challenge", match.Groups["MD5Challenge"].Value);
				response.Variables.Add("UrlToSubmitScript", match.Groups["UrlToSubmitScript"].Value);
				response.Interval = Convert.ToInt32(match.Groups["Interval"].Value);
			}

			return response;
		}
		/// <summary>
		/// Parse the response string into the approriate type
		/// </summary>
		private AudioscrobblerResponse ParseResponse(string responseString)
		{
			// if for any reason the response is empty (why would it be?),
			// return null
			if (responseString.Length == 0)
				return null;

			AudioscrobblerResponse response = new AudioscrobblerResponse();

			// figure out the response type and parse it approriately
			if (RequestStartsWith(responseString, "UPTODATE"))
			{
				response = GetResponse_UPTODATE(responseString);
			}
			else if (RequestStartsWith(responseString, "UPDATE"))
			{
				response = GetResponse_UPDATE(responseString);
			}
			else if (RequestStartsWith(responseString, "FAILED"))
			{
				response = GetResponse_FAILED(responseString);
			}
			else if (RequestStartsWith(responseString, "BADUSER"))
			{
				response = GetResponse_BADUSER(responseString);
			}
			else if (RequestStartsWith(responseString, "BADAUTH"))
			{
				response = GetResponse_BADAUTH(responseString);
			}
			else if (RequestStartsWith(responseString, "OK"))
			{
				response = GetResponse_OK(responseString);
			}
			else
			{
				response = GetResponse_UNKNOWN(responseString);
			}

			return response;
		}