/* Common Library */
function xGetElementById(e) {
	if(typeof(e)!='string') return e;
	if(document.getElementById) e=document.getElementById(e);
	else if(document.all) e=document.all[e];
	else e=null;
	return e;
}

function xtrim (str, charlist) {
    var whitespace, l = 0,
        i = 0;
    str += '';

    if (!charlist) {
        // default list
        whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
    } else {
        // preg_quote custom list
        charlist += '';
        whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
    }

    l = str.length;
    for (i = 0; i < l; i++) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(i);
            break;
        }
    }

    l = str.length;
    for (i = l - 1; i >= 0; i--) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(0, i + 1);
            break;
        }
    }

    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}

function jShow(elm) {
	//firstly check that elm is a reference or a text.
	if(typeof(elm) == 'string') {
		elm = xGetElementById(elm);
	}
	elm.style.display = 'block';
}

function jHide(elm) {
	//firstly check that elm is a reference or a text.
	if(typeof(elm) == 'string') {
		elm = xGetElementById(elm);
	}
	elm.style.display = 'none';
}
function xInnerHtml(e,h){
	if(!(e=xGetElementById(e)) || !xStr(e.innerHTML)) return null;
	var s = e.innerHTML;
	if (xStr(h)) {e.innerHTML = h;}
	return s;
}


function xStr(s){
	for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
	return true;
}

function addStyle(){
	document.getElementById('.');
	var headID = document.getElementsByTagName("head")[0];     
	var newStyle	= document.createElement('link');
	newStyle.type 	= 'text/css';
	newStyle.rel 	= 'stylesheet';
	newStyle.media  = 'all';
	newStyle.href 	= "http://www.openmicaustin.com/widgets/css/style.css";
	headID.appendChild(newStyle);
}

function json_decode (str_json) {
    var json = this.window.JSON;
    if (typeof json === 'object' && typeof json.parse === 'function') {
        try {
            return json.parse(str_json);
        } catch (err) {
            if (!(err instanceof SyntaxError)) {
                throw new Error('Unexpected error type in json_decode()');
            }
            this.php_js = this.php_js || {};
            this.php_js.last_error_json = 4; // usable by json_last_error()
            return null;
        }
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
    var j;
    var text = str_json;

    cx.lastIndex = 0;
    if (cx.test(text)) {
        text = text.replace(cx, function (a) {
            return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        });
    }

    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 j;
    }

    this.php_js = this.php_js || {};
    this.php_js.last_error_json = 4; // usable by json_last_error()
    return null;
}
function date (format, timestamp) {
    var that = this,
        jsdate, f, formatChr = /\\?([a-z])/gi,
        formatChrCb,
        // Keep this here (works, but for code commented-out
        // below for file size reasons)
        //, tal= [],
        _pad = function (n, c) {
            if ((n = n + "").length < c) {
                return new Array((++c) - n.length).join("0") + n;
            } else {
                return n;
            }
        },
        txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
        txt_ordin = {
            1: "st",
            2: "nd",
            3: "rd",
            21: "st",
            22: "nd",
            23: "rd",
            31: "st"
        };
    formatChrCb = function (t, s) {
        return f[t] ? f[t]() : s;
    };
    f = {
        // Day
        d: function () { // Day of month w/leading 0; 01..31
            return _pad(f.j(), 2);
        },
        D: function () { // Shorthand day name; Mon...Sun
            return f.l().slice(0, 3);
        },
        j: function () { // Day of month; 1..31
            return jsdate.getDate();
        },
        l: function () { // Full day name; Monday...Sunday
            return txt_words[f.w()] + 'day';
        },
        N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
            return f.w() || 7;
        },
        S: function () { // Ordinal suffix for day of month; st, nd, rd, th
            return txt_ordin[f.j()] || 'th';
        },
        w: function () { // Day of week; 0[Sun]..6[Sat]
            return jsdate.getDay();
        },
        z: function () { // Day of year; 0..365
            var a = new Date(f.Y(), f.n() - 1, f.j()),
                b = new Date(f.Y(), 0, 1);
            return Math.round((a - b) / 864e5) + 1;
        },

        // Week
        W: function () { // ISO-8601 week number
            var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
                b = new Date(a.getFullYear(), 0, 4);
            return 1 + Math.round((a - b) / 864e5 / 7);
        },

        // Month
        F: function () { // Full month name; January...December
            return txt_words[6 + f.n()];
        },
        m: function () { // Month w/leading 0; 01...12
            return _pad(f.n(), 2);
        },
        M: function () { // Shorthand month name; Jan...Dec
            return f.F().slice(0, 3);
        },
        n: function () { // Month; 1...12
            return jsdate.getMonth() + 1;
        },
        t: function () { // Days in month; 28...31
            return (new Date(f.Y(), f.n(), 0)).getDate();
        },

        // Year
        L: function () { // Is leap year?; 0 or 1
            return new Date(f.Y(), 1, 29).getMonth() === 1 | 0;
        },
        o: function () { // ISO-8601 year
            var n = f.n(),
                W = f.W(),
                Y = f.Y();
            return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9);
        },
        Y: function () { // Full year; e.g. 1980...2010
            return jsdate.getFullYear();
        },
        y: function () { // Last two digits of year; 00...99
            return (f.Y() + "").slice(-2);
        },

        // Time
        a: function () { // am or pm
            return jsdate.getHours() > 11 ? "pm" : "am";
        },
        A: function () { // AM or PM
            return f.a().toUpperCase();
        },
        B: function () { // Swatch Internet time; 000..999
            var H = jsdate.getUTCHours() * 36e2,
                // Hours
                i = jsdate.getUTCMinutes() * 60,
                // Minutes
                s = jsdate.getUTCSeconds(); // Seconds
            return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
        },
        g: function () { // 12-Hours; 1..12
            return f.G() % 12 || 12;
        },
        G: function () { // 24-Hours; 0..23
            return jsdate.getHours();
        },
        h: function () { // 12-Hours w/leading 0; 01..12
            return _pad(f.g(), 2);
        },
        H: function () { // 24-Hours w/leading 0; 00..23
            return _pad(f.G(), 2);
        },
        i: function () { // Minutes w/leading 0; 00..59
            return _pad(jsdate.getMinutes(), 2);
        },
        s: function () { // Seconds w/leading 0; 00..59
            return _pad(jsdate.getSeconds(), 2);
        },
        u: function () { // Microseconds; 000000-999000
            return _pad(jsdate.getMilliseconds() * 1000, 6);
        },

        // Timezone
        e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
            // The following works, but requires inclusion of the very large
            // timezone_abbreviations_list() function.
/*              return this.date_default_timezone_get();
*/
            throw 'Not supported (see source code of date() for timezone on how to add support)';
        },
        I: function () { // DST observed?; 0 or 1
            // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
            // If they are not equal, then DST is observed.
            var a = new Date(f.Y(), 0),
                // Jan 1
                c = Date.UTC(f.Y(), 0),
                // Jan 1 UTC
                b = new Date(f.Y(), 6),
                // Jul 1
                d = Date.UTC(f.Y(), 6); // Jul 1 UTC
            return 0 + ((a - c) !== (b - d));
        },
        O: function () { // Difference to GMT in hour format; e.g. +0200
            var a = jsdate.getTimezoneOffset();
            return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4);
        },
        P: function () { // Difference to GMT w/colon; e.g. +02:00
            var O = f.O();
            return (O.substr(0, 3) + ":" + O.substr(3, 2));
        },
        T: function () {
            return 'UTC';
        },
        Z: function () { // Timezone offset in seconds (-43200...50400)
            return -jsdate.getTimezoneOffset() * 60;
        },

        // Full Date/Time
        c: function () { // ISO-8601 date.
            return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb);
        },
        r: function () { // RFC 2822
            return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
        },
        U: function () { // Seconds since UNIX epoch
            return jsdate.getTime() / 1000 | 0;
        }
    };
    this.date = function (format, timestamp) {
        that = this;
        jsdate = ((typeof timestamp === 'undefined') ? new Date() : // Not provided
        (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
        new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
        );
        return format.replace(formatChr, formatChrCb);
    };
    return this.date(format, timestamp);
}
function strtotime (str, now) {
    var i, match, s, strTmp = '',
        parse = '';

    strTmp = str;
    strTmp = strTmp.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
    strTmp = strTmp.replace(/[\t\r\n]/g, ''); // unecessary chars
    if (strTmp == 'now') {
        return (new Date()).getTime() / 1000; // Return seconds, not milli-seconds
    } else if (!isNaN(parse = Date.parse(strTmp))) {
        return (parse / 1000);
    } else if (now) {
        now = new Date(now * 1000); // Accept PHP-style seconds
    } else {
        now = new Date();
    }

    strTmp = strTmp.toLowerCase();

    var __is = {
        day: {
            'sun': 0,
            'mon': 1,
            'tue': 2,
            'wed': 3,
            'thu': 4,
            'fri': 5,
            'sat': 6
        },
        mon: {
            'jan': 0,
            'feb': 1,
            'mar': 2,
            'apr': 3,
            'may': 4,
            'jun': 5,
            'jul': 6,
            'aug': 7,
            'sep': 8,
            'oct': 9,
            'nov': 10,
            'dec': 11
        }
    };

    var process = function (m) {
        var ago = (m[2] && m[2] == 'ago');
        var num = (num = m[0] == 'last' ? -1 : 1) * (ago ? -1 : 1);

        switch (m[0]) {
        case 'last':
        case 'next':
            switch (m[1].substring(0, 3)) {
            case 'yea':
                now.setFullYear(now.getFullYear() + num);
                break;
            case 'mon':
                now.setMonth(now.getMonth() + num);
                break;
            case 'wee':
                now.setDate(now.getDate() + (num * 7));
                break;
            case 'day':
                now.setDate(now.getDate() + num);
                break;
            case 'hou':
                now.setHours(now.getHours() + num);
                break;
            case 'min':
                now.setMinutes(now.getMinutes() + num);
                break;
            case 'sec':
                now.setSeconds(now.getSeconds() + num);
                break;
            default:
                var day;
                if (typeof(day = __is.day[m[1].substring(0, 3)]) != 'undefined') {
                    var diff = day - now.getDay();
                    if (diff == 0) {
                        diff = 7 * num;
                    } else if (diff > 0) {
                        if (m[0] == 'last') {
                            diff -= 7;
                        }
                    } else {
                        if (m[0] == 'next') {
                            diff += 7;
                        }
                    }
                    now.setDate(now.getDate() + diff);
                }
            }
            break;

        default:
            if (/\d+/.test(m[0])) {
                num *= parseInt(m[0], 10);

                switch (m[1].substring(0, 3)) {
                case 'yea':
                    now.setFullYear(now.getFullYear() + num);
                    break;
                case 'mon':
                    now.setMonth(now.getMonth() + num);
                    break;
                case 'wee':
                    now.setDate(now.getDate() + (num * 7));
                    break;
                case 'day':
                    now.setDate(now.getDate() + num);
                    break;
                case 'hou':
                    now.setHours(now.getHours() + num);
                    break;
                case 'min':
                    now.setMinutes(now.getMinutes() + num);
                    break;
                case 'sec':
                    now.setSeconds(now.getSeconds() + num);
                    break;
                }
            } else {
                return false;
            }
            break;
        }
        return true;
    };

    match = strTmp.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
    if (match != null) {
        if (!match[2]) {
            match[2] = '00:00:00';
        } else if (!match[3]) {
            match[2] += ':00';
        }

        s = match[1].split(/-/g);

        for (i in __is.mon) {
            if (__is.mon[i] == s[1] - 1) {
                s[1] = i;
            }
        }
        s[0] = parseInt(s[0], 10);

        s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + '';
        return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10);
    }

    var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?';

    match = strTmp.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
    if (match == null) {
        return false;
    }

    for (i = 0; i < match.length; i++) {
        if (!process(match[i].split(' '))) {
            return false;
        }
    }

    return (now.getTime() / 1000);
}


/* Cross Browser Ajax Requester */

var OpenmicApi = {  
	init:function(){
		addStyle();
		var init_html = '<!--<link rel="stylesheet" type="text/css" href="http://www.openmicaustin.com/widgets/css/style.css" media="all" />--><div id="openmic-widget-rbanner"><a id="openmic-widget-banner-link" href="http://www.openmic.us/" target="_blank"><img id="openmic-widget-banner" src="http://www.openmicaustin.com/img/spinner.gif" alt="AdBanner" border="0" /></a></div><div id="openmic-widget-frm"><select name="openmic-loc" id="openmic-loc"  onchange="OpenmicApi.search(this.value);"><option value="0">Choose Location</option><option value="3">Alaska</option><option value="8">Albuquerque</option><option value="66">Arkansas</option><option value="92">Athens</option><option value="2">Atlanta</option><option value="87">Auckland</option><option value="6">Austin</option><option value="5">Baltimore</option><option value="10">Bay Area</option><option value="77">Berlin</option><option value="11">Birmingham</option><option value="12">Boston</option><option value="13">Buffalo</option><option value="15">Charlotte </option><option value="14">Charlottesville</option><option value="16">Chicago</option><option value="17">Cincinnati</option><option value="18">Cleveland</option><option value="19">Columbus</option><option value="20">Dallas</option><option value="22">Denver</option><option value="23">Detroit</option><option value="86">Dublin</option><option value="79">Edinburgh</option><option value="76">Europe</option><option value="7">Hartford</option><option value="24">Hawaii</option><option value="25">Houston</option><option value="26">Idaho</option><option value="27">Indianapolis</option><option value="28">Iowa</option><option value="29">Jacksonville</option><option value="30">Kansas City</option><option value="32">Las Vegas</option><option value="82">London</option><option value="33">Long Island</option><option value="31">Los Angeles</option><option value="34">Louisiana</option><option value="35">Louisville</option><option value="85">Madrid</option><option value="36">Maine</option><option value="37">Miami</option><option value="38">Milwaukee</option><option value="39">Minneapolis</option><option value="40">Mississippi</option><option value="41">Montana</option><option value="42">Montreal</option><option value="43">Nashville</option><option value="44">Nebraska</option><option value="69">New Hampshire</option><option value="68">New Jersey</option><option value="90">New Orleans</option><option value="45">New York</option><option value="75">New Zealand</option><option value="74">North Dakota</option><option value="46">Oklahoma City</option><option value="67">OpenMic.US</option><option value="65">Orange County</option><option value="47">Orlando</option><option value="81">Paris</option><option value="48">Philadelphia</option><option value="4">Phoenix</option><option value="50">Pittsburgh</option><option value="51">Portland</option><option value="52">Rhode Island</option><option value="53">Richmond</option><option value="84">Rome</option><option value="54">Sacramento</option><option value="55">Salt Lake</option><option value="56">San Antonio</option><option value="57">San Diego</option><option value="58">San Francisco</option><option value="91">Savannah</option><option value="59">Seattle</option><option value="70">South Dakota</option><option value="60">St. Louis</option><option value="89">Sydney</option><option value="61">Tampa</option><option value="88">Toronto</option><option value="62">Upstate</option><option value="72">Vancouver</option><option value="71">Vermont</option><option value="83">Vienna</option><option value="63">Virginia</option><option value="21">Washington D.C.</option><option value="73">West Virginia</option><option value="64">Wyoming</option><option value="80">Zurich</option></select><img style="display:none;float: left;margin-left: 2px;margin-top: 38px;" src="http://www.openmicaustin.com/img/spinner.gif" alt="spinner" id="openmic-loader" /></div><div id="openmic-widget-result"></div><div id="openmic-widget-footer"><a href="http://www.openmic.us/" target="_blank" id="openmic-get-more-info"><img src="http://www.openmicaustin.com/widgets/images/footerbg.png" alt="More Info" border="0" /></a></div>';
		xInnerHtml('openmic-widget',init_html);
		this.search('');
	},

	createCORSRequest:function(method, url){
		var xhr = new XMLHttpRequest();
		if ("withCredentials" in xhr){
			xhr.open(method, url, true);
		} else if (typeof XDomainRequest != "undefined"){
			xhr = new XDomainRequest();
			xhr.open(method, url);
		} else {
			xhr = null;
		}
		return xhr;
	},

	displayResults:function(results_json){
		jArr = json_decode(results_json);
		
		if(typeof(jArr['domain'])!='undefined'){
			xGetElementById('openmic-get-more-info').href=jArr['domain'];
		}
		
		if(typeof(jArr['banner'])!='undefined'){
		id="openmic-widget-banner"
			if(jArr['banner']['url']!='_blank'){
				xGetElementById('openmic-widget-banner-link').href=jArr['banner']['url'];
			}
			if(jArr['banner']['src']!='_blank'){
				xGetElementById('openmic-widget-banner').src=jArr['banner']['src'];
			}
		}
		
		var output ='';
		if(jArr['events'].length>0){
			output +='<ul>';
			for(var i=0;i<jArr['events'].length;i++){
				output += '<li>'+jArr['events'][i]['Event']['title']+', '+
				jArr['events'][i]['Event']['venue_address']+', '+
				jArr['events'][i]['Event']['venue_city']+', '+
				jArr['events'][i]['Event']['venue_state']+', '+
				jArr['events'][i]['Event']['venue_zipcode']+', '+
				jArr['events'][i]['Event']['venue_phone']+' / '+
				date('h:ia',strtotime(date('Y')+'-'+date('m')+'-'+date('d')+' '+jArr['events'][i]['Event']['start_time']))+' - ('+
				jArr['events'][i]['ScheduleType']['name']+')';
				if(xtrim(jArr['events'][i]['Event']['venue_website']).length>0){
					output +=' - <a href="http://'+jArr['events'][i]['Event']['venue_website']+'" target="_blank">website</a></li>';
				}
			}
			output +='</ul>';
		}
		
		xInnerHtml('openmic-widget-result',output);
	},
  
	sanitizeMessageText:function(text) {
		text = text.replace('&amp;', '&');

		var link_regex = new RegExp("(([a-zA-Z]+:\/\/)([a-z][a-z0-9_\..-]*[a-z]{2,6})([a-zA-Z0-9\/*-_\?&%]*))", "i");
		text = text.replace(link_regex, '<a href="$1">$1</a>');

		var reply_regex = new RegExp("@([a-zA-Z0-9_]+)", "g");
		text = text.replace(reply_regex, '@<a href="http://twitter.com/$1">$1</a>');

		return(text);
	},
	
	search:function(location_id){
		if(parseInt(location_id)>0){
			jShow('openmic-loader');
			var request = this.createCORSRequest("get", "http://www.openmicaustin.com/web_services/get_events/" + location_id);
			if (request){
				request.onload = function(){
					OpenmicApi.displayResults(request.responseText);
					jHide('openmic-loader');
				};
				request.send();
			}
		}else{
			var request = this.createCORSRequest("get", "http://www.openmicaustin.com/web_services/get_events");
			if (request){
				request.onload = function(){
					OpenmicApi.displayResults(request.responseText);
				};
				request.send();
			}
		}
	}
};
