﻿// Copyright 2009 Microsoft Corporation
// JQuery extensions to support Hohm UI, requires jQuery.

// list of key codes (not neccessarilly ASCII) for named keys
// see also: http://unixpapa.com/js/key.html - good details on edge cases, etc.
var keyCodes = {
	enter: 13,
	escape: 27,
	tab: 9,
	backspace: 8,
	space: 32,
	leftArrow: 37,
	rightArrow: 39,
	upArrow: 38,
	downArrow: 40,
	shift: 16,
	control: 17,
	alt: 18,
	capsLock: 20,
	numLock: 144,
	insert: 45,
	home: 36,
	end: 35,
	pageUp: 33,
	pageDown: 34,
	editorKeys: [ 13, 27, 9, 8, 37, 38, 39, 40, 45, 36, 35, 33, 34 ]
};

// logs a message to the console, if available
function log(msg) { try { if (vars.logEnabled) { console.log(msg); } } catch (err) { } }

// Determines whether or not an array contains a given value
// arr = source array
// val = value to check for
function arrayContains(arr, val) {
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] == val) return true;
	}
	return false;
}

(function($) {

    // Adds a watermark attribute to an element, typically an input control
    // Shows and hides the watermark based on the value and state of the control
    // settings = list of settings (text, cssClass, attribute, onWatermark (callback))
    $.fn.watermark = function(settings) {
        var config = { text: null, cssClass: "watermark", attribute: "watermark", onWatermark: null };
        if (settings) $.extend(config, settings);
        return this.each(function() {
            if (config.onWatermark !== null) config.onWatermark(this);
            var str = config.text !== null ? config.text : $(this).val();
            $(this).addClass(config.cssClass).attr(config.attribute, str).val(str);
            if ($(this).is("input[type=text]")) {
                $(this).focus(function() {
                    if ($(this).val() == str) $(this).val("");
                    $(this).removeClass(config.cssClass);
                }).blur(function() {
                    if ($(this).val().length < 1) {
                        if (config.onWatermark) {
                            config.onWatermark(this);
                        }
                        $(this).addClass(config.cssClass).val(str);
                    }
                });
            }
        });
    };

    // Indicates whether an element (or the first element in a list) is currently set to
    // its watermark value
    $.fn.isWatermark = function(settings) {
        var config = { attribute: "watermark" };
        if (settings) $.extend(config, settings);
        var el = this.eq(0);
        if (el.attr(config.attribute) === undefined) {
            return false;
        }
        return el.val() == el.attr(config.attribute);
    };

    // Restricts input on an element to less than num characters
    // num = character limit for this element
    // settings = optional configuration values (len = limit or attr = attribute with limit)
    $.fn.maxLength = function(settings) {
        var config = {};
        if (settings) $.extend(config, settings);

        var handler = function() {
            var str = $(this).val(), max = 0;

            if (config.len) max = config.len;
            else if (config.attr) max = $(this).attr(config.attr);
            else return;

            if (isNaN(max) || max < 1 || !str || str.length < max) return;
            $(this).val(str.substring(0, max));
        };

        return this.each(function() {
            $(this).blur(handler); // previously also included .keydown(handler) - probably need to be smarter about which keys trigger processing
        });
    };

    // Filters keyboard input to character values that match a regular expression
    // regexp = regular expression to match valid single characters
    $.fn.filterInput = function(regexp) {
        return this.keypress(function(e) {
            var key = e.keyCode ? e.keyCode : e.charCode, val = String.fromCharCode(key), result = regexp.test(val);
            return arrayContains(keyCodes.editorKeys, key) ? true : result;
        });
    };

    // Renders (typically rounded) corners on some content element
    // imageUrl = image containing all four corners, will be 'sliced' by CSS
    // fullWidth, fullHeight = overall pixel dimensions of the image
    // cornerWidth, cornerHeight = pixel dimensions of the corners (all corners assumed to be the same)
    $.fn.corners = function(imageUrl, fullWidth, fullHeight, cornerWidth, cornerHeight) {
        return this.each(function() {
            var row = $("<div/>").width("100%").height(cornerHeight).css({ position: "relative" });
            var corner = $("<div/>").width(cornerWidth).height(cornerHeight).text(" ")
				.css({ position: "absolute", backgroundImage: "url(" + imageUrl + ")", backgroundRepeat: "no-repeat" });
            var arr = [
				corner.clone().css({ top: 0, left: 0, backgroundPosition: "0 0" }),
				corner.clone().css({ top: 0, right: 0, backgroundPosition: "-" + (fullWidth - cornerWidth) + "px 0px" }),
				corner.clone().css({ bottom: 0, left: 0, backgroundPosition: "0px -" + (fullHeight - cornerHeight) + "px" }),
				corner.clone().css({ bottom: 0, right: 0, backgroundPosition: "-" + (fullWidth - cornerWidth) + "px -" + (fullHeight - cornerHeight) + "px" })
			];
            var top = row.clone().append(arr[0]).append(arr[1]);
            var bottom = row.clone().append(arr[2]).append(arr[3]);
            $(this).prepend(top).append(bottom);
        });
    };
    
    // Gets the outer html for a given element
    $.fn.outerHTML = function() {
        return $('<div></div>').append( this.eq(0).clone() ).html();
    };

})(jQuery);

///<summary>Adds String.format functionality to the String object</summary>
///<remarks>
///This is just a basic implementation and doesn't really format the numbers
///Example use is String.format("{0} {1}!!!","hello","world"), gives you "hello world!!!" 
///</remarks>
String.format = String.prototype.format = function() {
    var i = 0;
    var string = (typeof (this) == "function" && !(i++)) ? arguments[0] : this;
    for (; i < arguments.length; i++)
        string = string.replace(/\{\d+?\}/, arguments[i]);
    return string;
}

// Removes extra spaces from the start and end of a string
String.prototype.trim = function() {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

