
if(navigator.userAgent.indexOf('iPhone') != -1 && navigator.userAgent.indexOf('Safari') == -1)
	navigator.deviceName = 'iPhoneApp';
else if(navigator.userAgent.indexOf('ecoweb1.1') != -1)
	navigator.deviceName = 'androidApp';
else if(navigator.userAgent.indexOf('iPhone') != -1)
	 navigator.deviceName = 'iPhoneWeb';
else if(navigator.userAgent.indexOf('Android') != -1)
	 navigator.deviceName = 'androidWeb';
else if(navigator.userAgent.indexOf('iPad') != -1)
	navigator.deviceName = 'iPad';
else if(navigator.userAgent.indexOf('iPhone') != -1 ||navigator.userAgent.indexOf('Android') != -1 ||navigator.userAgent.indexOf('Mobile') != -1)
	navigator.deviceName = 'mobile';
else
	navigator.deviceName = 'desktop';


/*
 * app과 web을 연동해주는 js, 아이폰에서 사용
 */


var _anomFunkMap = {};
var _anomFunkMapNextId = 0; 

function anomToNameFunk(fun)
{
	var funkId = "f" + _anomFunkMapNextId++;
	var funk = function()
	{
		fun.apply(this,arguments);
		_anomFunkMap[funkId] = null;
		delete _anomFunkMap[funkId];	
	};
	_anomFunkMap[funkId] = funk;

	return "_anomFunkMap." + funkId;
}

function GetFunctionName(fn)
{
  if (fn) 
  {
      var m = fn.toString().match(/^\s*function\s+([^\s\(]+)/);
      return m ? m[1] : anomToNameFunk(fn);
  } else {
    return null;
  }
}


if( navigator.userAgent.indexOf("iPhone") != -1 && navigator.userAgent.indexOf("Safari") == -1 ) {
	if (typeof(DeviceInfo) != 'object')
	    DeviceInfo = {};
	
	/**
	 * This represents the PhoneGap API itself, and provides a global namespace for accessing
	 * information about the state of PhoneGap.
	 * @class
	 */
	iLibropiaApp = {
	    queue: {
	        ready: true,
	        commands: [],
	        timer: null
	    },
	    _constructors: []
	};
	
	/**
	 * Boolean flag indicating if the PhoneGap API is available and initialized.
	 */ // TODO: Remove this, it is unused here ... -jm
	iLibropiaApp.available = DeviceInfo.uuid != undefined;
	
	/**
	 * Add an initialization function to a queue that ensures it will run and initialize
	 * application constructors only once PhoneGap has been initialized.
	 * @param {Function} func The function callback you want run once PhoneGap is initialized
	 */
	iLibropiaApp.addConstructor = function(func) {
	    var state = document.readyState;
	    if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null )
		{
			func();
		}
	    else
		{
	        iLibropiaApp._constructors.push(func);
		}
	};
	
	(function() 
	 {
	    var timer = setInterval(function()
		{
								
			var state = document.readyState;
								
	        if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null )
			{
				clearInterval(timer); // stop looking
				if (typeof navigator.ios == "undefined") navigator.ios = {};
				// run our constructors list
				while (iLibropiaApp._constructors.length > 0) 
				{
					var constructor = iLibropiaApp._constructors.shift();
					try 
					{
						constructor();
					} 
					catch(e) 
					{
						if (typeof(debug['log']) == 'function')
						{
							debug.log("Failed to run constructor: " + debug.processMessage(e));
						}
						else
						{
							alert("Failed to run constructor: " + e.message);
						}
					}
	            }
				// all constructors run, now fire the deviceready event
				var e = document.createEvent('Events'); 
				e.initEvent('deviceready');
				document.dispatchEvent(e);
			}
	    }, 1);
	})();
	
	
	/**
	 * Execute a PhoneGap command in a queued fashion, to ensure commands do not
	 * execute with any race conditions, and only run when PhoneGap is ready to
	 * recieve them.
	 * @param {String} command Command to be run in PhoneGap, e.g. "ClassName.method"
	 * @param {String[]} [args] Zero or more arguments to pass to the method
	 */
	iLibropiaApp.exec = function() {
	    iLibropiaApp.queue.commands.push(arguments);
	    if (iLibropiaApp.queue.timer == null)
	        iLibropiaApp.queue.timer = setInterval(iLibropiaApp.run_command, 10);
	};
	
	/**
	 * Internal function used to dispatch the request to PhoneGap.  It processes the
	 * command queue and executes the next command on the list.  If one of the
	 * arguments is a JavaScript object, it will be passed on the QueryString of the
	 * url, which will be turned into a dictionary on the other end.
	 * @private
	 */
	iLibropiaApp.run_command = function() {
	    if (!iLibropiaApp.available || !iLibropiaApp.queue.ready)
	        return;
	
	    iLibropiaApp.queue.ready = false;
	
	    var args = iLibropiaApp.queue.commands.shift();
	    if (iLibropiaApp.queue.commands.length == 0) {
	        clearInterval(iLibropiaApp.queue.timer);
	        iLibropiaApp.queue.timer = null;
	    }
	
	    var uri = [];
	    var dict = null;
	    for (var i = 1; i < args.length; i++) {
	        var arg = args[i];
	        if (arg == undefined || arg == null)
	            arg = '';
	        if (typeof(arg) == 'object')
	            dict = arg;
	        else
	            uri.push(encodeURIComponent(arg));
	    }
	    var url = "iLibropiaApp://" + args[0] + "/" + uri.join("/");
	    if (dict != null) {
	        var query_args = [];
	        for (var name in dict) {
	            if (typeof(name) != 'string')
	                continue;
	            query_args.push(encodeURIComponent(name) + "=" + encodeURIComponent(dict[name]));
	        }
	        if (query_args.length > 0)
	            url += "?" + query_args.join("&");
	    }
	    document.location = url;
	
	};
	/**
	 * This class contains acceleration information
	 * @constructor
	 * @param {Number} x The force applied by the device in the x-axis.
	 * @param {Number} y The force applied by the device in the y-axis.
	 * @param {Number} z The force applied by the device in the z-axis.
	 */
	function Acceleration(x, y, z) {
		/**
		 * The force applied by the device in the x-axis.
		 */
		this.x = x;
		/**
		 * The force applied by the device in the y-axis.
		 */
		this.y = y;
		/**
		 * The force applied by the device in the z-axis.
		 */
		this.z = z;
		/**
		 * The time that the acceleration was obtained.
		 */
		this.timestamp = new Date().getTime();
	}
	
	/**
	 * This class specifies the options for requesting acceleration data.
	 * @constructor
	 */
	function AccelerationOptions() {
		/**
		 * The timeout after which if acceleration data cannot be obtained the errorCallback
		 * is called.
		 */
		this.timeout = 10000;
	}
	/**
	 * This class provides access to device accelerometer data.
	 * @constructor
	 */
	function Accelerometer() 
	{
		/**
		 * The last known acceleration.
		 */
		this.lastAcceleration = new Acceleration(0,0,0);
	}
	
	/**
	 * Asynchronously aquires the current acceleration.
	 * @param {Function} successCallback The function to call when the acceleration
	 * data is available
	 * @param {Function} errorCallback The function to call when there is an error 
	 * getting the acceleration data.
	 * @param {AccelerationOptions} options The options for getting the accelerometer data
	 * such as timeout.
	 */
	Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) {
		// If the acceleration is available then call success
		// If the acceleration is not available then call error
		
		// Created for iPhone, Iphone passes back _accel obj litteral
		if (typeof successCallback == "function") {
			successCallback(this.lastAcceleration);
		}
	};
	
	// private callback called from Obj-C by name
	Accelerometer.prototype._onAccelUpdate = function(x,y,z)
	{
	   this.lastAcceleration = new Acceleration(x,y,z);
	};
	
	/**
	 * Asynchronously aquires the acceleration repeatedly at a given interval.
	 * @param {Function} successCallback The function to call each time the acceleration
	 * data is available
	 * @param {Function} errorCallback The function to call when there is an error 
	 * getting the acceleration data.
	 * @param {AccelerationOptions} options The options for getting the accelerometer data
	 * such as timeout.
	 */
	
	Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) {
		//this.getCurrentAcceleration(successCallback, errorCallback, options);
		// TODO: add the interval id to a list so we can clear all watches
	 	var frequency = (options != undefined && options.frequency != undefined) ? options.frequency : 10000;
		var updatedOptions = {
			desiredFrequency:frequency 
		};
		iLibropiaApp.exec("Accelerometer.start",options);
	
		return setInterval(function() {
			navigator.ios.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options);
		}, frequency);
	};
	
	/**
	 * Clears the specified accelerometer watch.
	 * @param {String} watchId The ID of the watch returned from #watchAcceleration.
	 */
	Accelerometer.prototype.clearWatch = function(watchId) {
		iLibropiaApp.exec("Accelerometer.stop");
		clearInterval(watchId);
	};
	
	iLibropiaApp.addConstructor(function() {
	    if (typeof navigator.ios.accelerometer == "undefined") navigator.ios.accelerometer = new Accelerometer();
	});
	
	
	/**
	 * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
	 * phone, etc.
	 * @constructor
	 */
	function Device() 
	{
	    this.platform = null;
	    this.version  = null;
	    this.name     = null;
	    this.phonegap      = null;
	    this.uuid     = null;
	    try 
		{      
			this.platform = DeviceInfo.platform;
			this.version  = DeviceInfo.version;
			this.name     = DeviceInfo.name;
			this.phonegap = DeviceInfo.gap;
			this.uuid     = DeviceInfo.uuid;
	
	    } 
		catch(e) 
		{
	        // TODO: 
	    }
		this.available = iLibropiaApp.available = this.uuid != null;
	}
	
	iLibropiaApp.addConstructor(function() {
	    navigator.ios.device = new Device();
	});
	
	
	/**
	 * This class provides access to device GPS data.
	 * @constructor
	 */
	function Geolocation() {
	    /**
	     * The last known GPS position.
	     */
	    this.lastPosition = null;
	    this.lastError = null;
	};
	
	/**
	 * Asynchronously aquires the current position.
	 * @param {Function} successCallback The function to call when the position
	 * data is available
	 * @param {Function} errorCallback The function to call when there is an error 
	 * getting the position data.
	 * @param {PositionOptions} options The options for getting the position data
	 * such as timeout.
	 * PositionOptions.forcePrompt:Bool default false, 
	 * - tells iPhone to prompt the user to turn on location services.
	 * - may cause your app to exit while the user is sent to the Settings app
	 * PositionOptions.distanceFilter:double aka Number
	 * - used to represent a distance in meters.
	PositionOptions
	{
	   desiredAccuracy:Number
	   - a distance in meters 
			< 10   = best accuracy  ( Default value )
			< 100  = Nearest Ten Meters
			< 1000 = Nearest Hundred Meters
			< 3000 = Accuracy Kilometers
			3000+  = Accuracy 3 Kilometers
			
		forcePrompt:Boolean default false ( iPhone Only! )
	    - tells iPhone to prompt the user to turn on location services.
		- may cause your app to exit while the user is sent to the Settings app
		
		distanceFilter:Number
		- The minimum distance (measured in meters) a device must move laterally before an update event is generated.
		- measured relative to the previously delivered location
		- default value: null ( all movements will be reported )
		
	}
	
	 */
	Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) 
	{
	    var referenceTime = 0;
		
		if(this.lastError != null)
		{
			if(typeof(errorCallback) == 'function')
			{
				errorCallback.call(null,this.lastError);
			}
			this.stop();
			return;
		}
	
		this.start(options);
	
	    var timeout = 30000; // defaults
	    var interval = 2000;
		
	    if (options && options.interval)
	        interval = options.interval;
	
	    if (typeof(successCallback) != 'function')
	        successCallback = function() {};
	    if (typeof(errorCallback) != 'function')
	        errorCallback = function() {};
	
	    var dis = this;
	    var delay = 0;
		var timer;
		var onInterval = function()
		{
			delay += interval;
			if(dis.lastPosition != null && dis.lastPosition.timestamp > referenceTime)
			{
				clearInterval(timer);
	            successCallback(dis.lastPosition);
			}
			else if(delay > timeout)
			{
				clearInterval(timer);
	            errorCallback("Error Timeout");
			}
			else if(dis.lastError != null)
			{
				clearInterval(timer);
				errorCallback(dis.lastError);
			}
		};
	    timer = setInterval(onInterval,interval);     
	};
	
	/**
	 * Asynchronously aquires the position repeatedly at a given interval.
	 * @param {Function} successCallback The function to call each time the position
	 * data is available
	 * @param {Function} errorCallback The function to call when there is an error 
	 * getting the position data.
	 * @param {PositionOptions} options The options for getting the position data
	 * such as timeout and the frequency of the watch.
	 */
	Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) {
		// Invoke the appropriate callback with a new Position object every time the implementation 
		// determines that the position of the hosting device has changed. 
		
		this.getCurrentPosition(successCallback, errorCallback, options);
		var frequency = (options && options.frequency) ? options.frequency : 10000; // default 10 second refresh
	
		var that = this;
		return setInterval(function() 
		{
			that.getCurrentPosition(successCallback, errorCallback, options);
		}, frequency);
	
	};
	
	
	/**	
	 * Clears the specified position watch.
	 * @param {String} watchId The ID of the watch returned from #watchPosition.
	 */
	Geolocation.prototype.clearWatch = function(watchId) {
		clearInterval(watchId);
	};
	
	/**
	 * Called by the geolocation framework when the current location is found.
	 * @param {PositionOptions} position The current position.
	 */
	Geolocation.prototype.setLocation = function(position) 
	{
		this.lastError = null;
	    this.lastPosition = position;
	
	};
	
	/**
	 * Called by the geolocation framework when an error occurs while looking up the current position.
	 * @param {String} message The text of the error message.
	 */
	Geolocation.prototype.setError = function(error) {
	    this.lastError = error;
	};
	
	Geolocation.prototype.start = function(args) {
	    iLibropiaApp.exec("Location.startLocation", args);
	};
	
	Geolocation.prototype.stop = function() {
	    iLibropiaApp.exec("Location.stopLocation");
	};
	
	// replace origObj's functions ( listed in funkList ) with the same method name on proxyObj
	// this is a workaround to prevent UIWebView/MobileSafari default implementation of GeoLocation
	// because it includes the full page path as the title of the alert prompt
	function __proxyObj(origObj,proxyObj,funkList)
	{
	    var replaceFunk = function(org,proxy,fName)
	    { 
	        org[fName] = function()
	        { 
	           return proxy[fName].apply(proxy,arguments); 
	        }; 
	    };
		 
	    for(var v in funkList) { replaceFunk(origObj,proxyObj,funkList[v]);}
	}
	
	
	iLibropiaApp.addConstructor(function() 
	{
	    if (typeof navigator.ios._geo == "undefined") 
	    {
	        navigator.ios._geo = new Geolocation();
	        __proxyObj(navigator.geolocation, navigator.ios._geo,
	                 ["setLocation","getCurrentPosition","watchPosition",
	                  "clearWatch","setError","start","stop"]);
	
	    }
	
	});
	
	function Map() {
		
	}
	
	/**
	 * Shows a native map on the device with pins at the given positions.
	 * @param {Array} positions
	 */
	Map.prototype.show = function(eleArray, title, useGPS, center, clickJS,
			leftButtonVisible, leftButtonTitle, leftButtonClickJS,
			rightButtonVisible, rightButtonTitle, rightButtonClickJS) {

		var options = {};
		if(title) {
			options.title = title;
		}
		if(useGPS) {
			options.useGPS = useGPS;
		} else {
			options.useGPS = '1';
		}
		if(center) {
			options.center = center;
		} else {
			if(options.useGPS == '1') {
				options.center = '(0,0)';
			} else {
				options.center = "("+ eleArray.split("/")[0].split('|')[2] + ")";
			}
		}
		
		if(clickJS) {
			options.clickJS = clickJS;
		} else {
			options.clickJS = '(function(){})';
		}
		
		if(leftButtonVisible) {
			options.leftButtonVisible = leftButtonVisible;
			if(leftButtonTitle) {
				options.leftButtonTitle = leftButtonTitle;
			} else {
				options.leftButtonTitle = '이전';
			}
			if(leftButtonClickJS) {
				options.leftButtonClickJS = leftButtonClickJS;
			} else {
				options.leftButtonClickJS = '(function(){})';
			}
		} else {
			options.leftButtonVisible = '0';
		}
		if(rightButtonVisible) {
			options.rightButtonVisible = rightButtonVisible;
			if(rightButtonTitle) {
				options.rightButtonTitle = rightButtonTitle;
			} else {
				options.rightButtonTitle = '다음';
			}
			if(rightButtonClickJS) {
				options.rightButtonClickJS = rightButtonClickJS;
			} else {
				options.rightButtonClickJS = '(function(){})';
			}
		} else {
			options.rightButtonVisible = '0';
		}
		
		iLibropiaApp.exec("Map.show",eleArray,options);
	};
	
	iLibropiaApp.addConstructor(function() {
	    if (typeof navigator.ios.map == "undefined") navigator.ios.map = new Map();
	});
	
function ARView() {
		
	}
	
	/**
	 * Shows a native map on the device with pins at the given positions.
	 * @param {Array} positions
	 */
	ARView.prototype.show = function(eleArray, clickJS, userLocation, searchDistance, xmlURL) {
		var options = {};
		if(eleArray.indexOf('|') == -1) {
			alert('검색결과가 없습니다.');
			return;
		}
		if(clickJS) {
			options.clickJS = clickJS;
		} else {
			options.clickJS = '(function(){})';
		}
		if(userLocation) {
			options.userLocation = userLocation;
		}
		if(searchDistance) {
			options.searchDistance = searchDistance;
		} else {
			options.searchDistance = '5';
		}
		if(xmlURL) {
			options.xmlURL = xmlURL;
		}
		iLibropiaApp.exec("ARView.show",eleArray,options);
	};
	
	iLibropiaApp.addConstructor(function() {
	    if (typeof navigator.ios.arview == "undefined") navigator.ios.arview = new ARView();
	});
	
	//////////////////////////////////////////////////////////////////////////////////////////
	function Homepage() {
		
	}
	
	/**
	 * Shows a native map on the device with pins at the given positions.
	 * @param {Array} positions
	 */
	Homepage.prototype.show = function(url,title,
			leftButtonVisible, leftButtonTitle, leftButtonClickJS,
			rightButtonVisible, rightButtonTitle, rightButtonClickJS) {
		if(!url) {
			return;
		}
		var options = {};
		if(title) {
			options.title = title;
		}
			
		if(leftButtonVisible) {
			options.leftButtonVisible = leftButtonVisible;
			if(leftButtonTitle) {
				options.leftButtonTitle = leftButtonTitle;
			} else {
				options.leftButtonTitle = '이전';
			}
			if(leftButtonClickJS) {
				options.leftButtonClickJS = leftButtonClickJS;
			} else {
				options.leftButtonClickJS = '(function(){})';
			}
		} else {
			options.leftButtonVisible = '0';
		}
		if(rightButtonVisible) {
			options.rightButtonVisible = rightButtonVisible;
			if(rightButtonTitle) {
				options.rightButtonTitle = rightButtonTitle;
			} else {
				options.rightButtonTitle = '다음';
			}
			if(rightButtonClickJS) {
				options.rightButtonClickJS = rightButtonClickJS;
			} else {
				options.rightButtonClickJS = '(function(){})';
			}
		} else {
			options.rightButtonVisible = '0';
		}
		
		iLibropiaApp.exec("Homepage.show",url,options);
	};
	
	iLibropiaApp.addConstructor(function() {
	    if (typeof navigator.ios.homepage == "undefined") navigator.ios.homepage = new Homepage();
	});
	//////////////////////////////////////////////////////////////////////////////////////////

	
	/**
	 * This class contains position information.
	 * @param {Object} lat
	 * @param {Object} lng
	 * @param {Object} acc
	 * @param {Object} alt
	 * @param {Object} altacc
	 * @param {Object} head
	 * @param {Object} vel
	 * @constructor
	 */
	function Position(coords, timestamp) {
		this.coords = coords;
	        this.timestamp = new Date().getTime();
	}
	
	function Coordinates(lat, lng, alt, acc, head, vel, altAcc) {
		/**
		 * The latitude of the position.
		 */
		this.latitude = lat;
		/**
		 * The longitude of the position,
		 */
		this.longitude = lng;
		/**
		 * The accuracy of the position.
		 */
		this.accuracy = acc;
		/**
		 * The altitude of the position.
		 */
		this.altitude = alt;
		/**
		 * The direction the device is moving at the position.
		 */
		this.heading = head;
		/**
		 * The velocity with which the device is moving at the position.
		 */
		this.speed = vel;
		/**
		 * The altitude accuracy of the position.
		 */
		this.altitudeAccuracy = (altacc != 'undefined') ? altacc : null; 
	}
	
	/**
	 * This class specifies the options for requesting position data.
	 * @constructor
	 */
	function PositionOptions() {
		/**
		 * Specifies the desired position accuracy.
		 */
		this.enableHighAccuracy = true;
		/**
		 * The timeout after which if position data cannot be obtained the errorCallback
		 * is called.
		 */
		this.timeout = 10000;
	}
	
	/**
	 * This class contains information about any GSP errors.
	 * @constructor
	 */
	function PositionError() {
		this.code = null;
		this.message = "";
	}
	
	PositionError.UNKNOWN_ERROR = 0;
	PositionError.PERMISSION_DENIED = 1;
	PositionError.POSITION_UNAVAILABLE = 2;
	PositionError.TIMEOUT = 3;
	
	
	/**
	 * This class provides access to the telephony features of the device.
	 * @constructor
	 */
	function Telephony() {
		
	}
	
	/**
	 * Calls the specifed number.
	 * @param {Integer} number The number to be called.
	 */
	Telephony.prototype.call = function(number) {
		location.href = "tel:"+number;
	};
	
	iLibropiaApp.addConstructor(function() {
	    if (typeof navigator.ios.telephony == "undefined") navigator.ios.telephony = new Telephony();
	});
	/**
	 * This class exposes mobile phone interface controls to JavaScript, such as
	 * native tab and tool bars, etc.
	 * @constructor
	 */
	function UIControls() {
	    this.tabBarTag = 0;
	    this.tabBarCallbacks = {};
	}
	
	/**
	 * Create a native tab bar that can have tab buttons added to it which can respond to events.
	 */
	UIControls.prototype.createTabBar = function() {
	    iLibropiaApp.exec("UIControls.createTabBar");
	};
	
	/**
	 * Show a tab bar.  The tab bar has to be created first.
	 * @param {Object} [options] Options indicating how the tab bar should be shown:
	 * - \c height integer indicating the height of the tab bar (default: \c 49)
	 * - \c position specifies whether the tab bar will be placed at the \c top or \c bottom of the screen (default: \c bottom)
	 */
	UIControls.prototype.showTabBar = function(options) {
	    if (!options) options = {};
	    iLibropiaApp.exec("UIControls.showTabBar", options);
	};
	
	/**
	 * Hide a tab bar.  The tab bar has to be created first.
	 */
	UIControls.prototype.hideTabBar = function(animate) {
	    if (animate == undefined || animate == null)
	        animate = true;
	    iLibropiaApp.exec("UIControls.hideTabBar", { animate: animate });
	};
	
	/**
	 * Create a new tab bar item for use on a previously created tab bar.  Use ::showTabBarItems to show the new item on the tab bar.
	 *
	 * If the supplied image name is one of the labels listed below, then this method will construct a tab button
	 * using the standard system buttons.  Note that if you use one of the system images, that the \c title you supply will be ignored.
	 *
	 * <b>Tab Buttons</b>
	 *   - tabButton:More
	 *   - tabButton:Favorites
	 *   - tabButton:Featured
	 *   - tabButton:TopRated
	 *   - tabButton:Recents
	 *   - tabButton:Contacts
	 *   - tabButton:History
	 *   - tabButton:Bookmarks
	 *   - tabButton:Search
	 *   - tabButton:Downloads
	 *   - tabButton:MostRecent
	 *   - tabButton:MostViewed
	 * @param {String} name internal name to refer to this tab by
	 * @param {String} [title] title text to show on the tab, or null if no text should be shown
	 * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown
	 * @param {Object} [options] Options for customizing the individual tab item
	 *  - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden
	 */
	UIControls.prototype.createTabBarItem = function(name, label, image, options) {
	    var tag = this.tabBarTag++;
	    if (options && 'onSelect' in options && typeof(options['onSelect']) == 'function') {
	        this.tabBarCallbacks[tag] = options.onSelect;
	        delete options.onSelect;
	    }
	    iLibropiaApp.exec("UIControls.createTabBarItem", name, label, image, tag, options);
	};
	
	/**
	 * Update an existing tab bar item to change its badge value.
	 * @param {String} name internal name used to represent this item when it was created
	 * @param {Object} options Options for customizing the individual tab item
	 *  - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden
	 */
	UIControls.prototype.updateTabBarItem = function(name, options) {
	    if (!options) options = {};
	    iLibropiaApp.exec("UIControls.updateTabBarItem", name, options);
	};
	
	/**
	 * Show previously created items on the tab bar
	 * @param {String} arguments... the item names to be shown
	 * @param {Object} [options] dictionary of options, notable options including:
	 *  - \c animate indicates that the items should animate onto the tab bar
	 * @see createTabBarItem
	 * @see createTabBar
	 */
	UIControls.prototype.showTabBarItems = function() {
		var parameters = [ "UIControls.showTabBarItems" ];
	    for (var i = 0; i < arguments.length; i++) {
	        parameters.push(arguments[i]);
	    }
	    iLibropiaApp.exec.apply(this, parameters);
	};
	
	/**
	 * Show all previously created items on the tab bar
	 * @see createTabBarItem
	 * @see createTabBar
	 */
	UIControls.prototype.showAllTabBarItems = function() {
	    var parameters = [ "UIControls.showTabBarItems" ];
	    for (var i = 0; i < this.tabBarTag; i++) {
	        parameters.push(i + '');
	    }
	    iLibropiaApp.exec.apply(this, parameters);
	};
	
	/**
	 * Manually select an individual tab bar item, or nil for deselecting a currently selected tab bar item.
	 * @param {String} tabName the name of the tab to select, or null if all tabs should be deselected
	 * @see createTabBarItem
	 * @see showTabBarItems
	 */
	UIControls.prototype.selectTabBarItem = function(tab) {
	    iLibropiaApp.exec("UIControls.selectTabBarItem", tab);
	};
	
	/**
	 * Function called when a tab bar item has been selected.
	 * @param {Number} tag the tag number for the item that has been selected
	 */
	UIControls.prototype.tabBarItemSelected = function(tag) {
	    if (typeof(this.tabBarCallbacks[tag]) == 'function')
	        this.tabBarCallbacks[tag]();
	};
	
	UIControls.prototype.createNavBar = function() {
	    iLibropiaApp.exec("UIControls.createNavBar");
	};
	UIControls.prototype.setNavBarTitle = function(title) {
		var options = {};
		options.title = title;
	    iLibropiaApp.exec("UIControls.setNavBarTitle",options);
	};
	UIControls.prototype.setNavBarImage = function( style ) {
		var options = {};
		options.style = style;
	    iLibropiaApp.exec("UIControls.setNavBarImage",options);
	};
	UIControls.prototype.setNavBarTextColor = function( color ) {
		var options = {};
		options.color = color;
	    iLibropiaApp.exec("UIControls.setNavBarTextColor",options);
	};
	UIControls.prototype.setNavButtonTextColor = function( color ) {
		var options = {};
		options.color = color;
	    iLibropiaApp.exec("UIControls.setNavButtonTextColor",options);
	};
	UIControls.prototype.setNavBarLeftButton = function(isVisible, title, clickJS, style) {
		if(isVisible == '1')
		{
			var options = {};
			options.isVisible = isVisible;
			options.title = title;
			options.clickJS = clickJS;
			if(style == 'button' || style == 'back' || style == 'info')
			{
				options.style = style;
			} else
			{
				options.style = 'button';
			}
		    iLibropiaApp.exec("UIControls.setNavBarLeftButton",options);
		}
		else
		{
			var options = {};
			options.isVisible = '0';
			options.title = '';
			options.clickJS = '(function(){})';
			if(style == 'button' || style == 'back' || style == 'info')
			{
				options.style = style;
			} else
			{
				options.style = 'button';
			}
		    iLibropiaApp.exec("UIControls.setNavBarLeftButton",options);
		}
			
	};
	UIControls.prototype.setNavBarRightButton = function(isVisible, title, clickJS, style) {
		if(isVisible == '1')
		{
			var options = {};
			options.isVisible = isVisible;
			options.title = title;
			options.clickJS = clickJS;
			options.style = style;
		    iLibropiaApp.exec("UIControls.setNavBarRightButton",options);
		}
		else
		{
			var options = {};
			options.isVisible = '0';
			options.title = '';
			options.clickJS = '(function(){})';
			options.style = '';
		    iLibropiaApp.exec("UIControls.setNavBarRightButton",options);
		}
	};
	UIControls.prototype.showNavBar = function() {
	    iLibropiaApp.exec("UIControls.showNavBar");
	};
	UIControls.prototype.hideNavBar = function() {
	    iLibropiaApp.exec("UIControls.hideNavBar");
	};
	
	/**
	 * Create a toolbar.
	 */
	UIControls.prototype.createToolBar = function() {
	    iLibropiaApp.exec("UIControls.createToolBar");
	};
	
	/**
	 * Function called when a tab bar item has been selected.
	 * @param {String} title the title to set within the toolbar
	 */
	UIControls.prototype.setToolBarTitle = function(title) {
	    iLibropiaApp.exec("UIControls.setToolBarTitle", title);
	};
	
	iLibropiaApp.addConstructor(function() {
		if (typeof navigator.ios.uicontrols == "undefined") navigator.ios.uicontrols = new UIControls();
	});
	
	/**
	 * This class contains information about any NetworkStatus.
	 * @constructor
	 */
	function NetworkStatus() {
		this.code = null;
		this.message = "";
	}
	
	NetworkStatus.NOT_REACHABLE = 0;
	NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1;
	NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2;
	
	/**
	 * This class provides access to device Network data (reachability).
	 * @constructor
	 */
	function Network() {
	    /**
	     * The last known Network status.
		 * { hostName: string, ipAddress: string, 
			remoteHostStatus: int(0/1/2), internetConnectionStatus: int(0/1/2), localWiFiConnectionStatus: int (0/2) }
	     */
		this.lastReachability = null;
	};
	
	/**
	 * 
	 * @param {Function} successCallback
	 * @param {Function} errorCallback
	 * @param {Object} options (isIpAddress:boolean)
	 */
	Network.prototype.isReachable = function(hostName, successCallback, options) {
		iLibropiaApp.exec("Network.isReachable", hostName, GetFunctionName(successCallback), options);
	};
	
	/**
	 * Called by the geolocation framework when the reachability status has changed.
	 * @param {Reachibility} reachability The current reachability status.
	 */
	Network.prototype.updateReachability = function(reachability) {
	    this.lastReachability = reachability;
	};
	
	iLibropiaApp.addConstructor(function() {
	    if (typeof navigator.ios.network == "undefined") navigator.ios.network = new Network();
	});
	
	/**
	 * This class provides access camera to read Barcode.
	 * @constructor
	 */
	function BarcodeReader() {
	    
	};
	
	/**
	 * 
	 * @param {Function} successCallback
	 * @param {Function} closeCallback
	 */
	/*BarcodeReader.prototype.readStart = function(successCallBack, closeCallback) {
		iLibropiaApp.exec("BarcodeReader.readStart", GetFunctionName(successCallback), GetFunctionName(closeCallback));
	};*/

	BarcodeReader.prototype.readStart = function(successCallBack, closeCallBack) {
		if(closeCallBack)
			iLibropiaApp.exec("BarcodeReader.readStart", successCallBack, closeCallBack);
		else
			iLibropiaApp.exec("BarcodeReader.readStart", successCallBack);
	};
	
	iLibropiaApp.addConstructor(function() {
	    navigator.ios.barcodeReader = new BarcodeReader();
	});
}


if( navigator.deviceName == 'desktop' || navigator.deviceName == 'mobile' ) {
	window.addEventListener("load", _onLoaded, false);
	function _onLoaded() {
		var e = document.createEvent('Events');
		e.initEvent('deviceready');
		document.dispatchEvent(e);
	}
	navigator.browser = {
	};
	
	function bUIControls(){
		this.navBarTitle = '';
		this.leftButtonVisible = false;
		this.leftButtonTitle = '';
		this.leftButtonClickJS = '';
		this.rightButtonVisible = false;
		this.rightButtonTitle = '';
		this.rightButtonClickJS = '';
	};
	bUIControls.prototype.setNavBarTitle = function(title) {
		this.navBarTitle = title;
	};
	bUIControls.prototype.setNavBarLeftButton = function(isVisible, title, clickJS, style) {
		if(isVisible == '1')
		{
			this.leftButtonVisible = true;
			this.leftButtonTitle = title;
			this.leftButtonClickJS = clickJS;
			if(style == 'info') {
				this.leftButtonTitle = '�젙蹂�';
			}
		}
	};
	bUIControls.prototype.setNavBarRightButton = function(isVisible, title, clickJS, style) {
		if(isVisible == '1')
		{
			this.rightButtonVisible = true;
			this.rightButtonTitle = title;
			this.rightButtonClickJS = clickJS;
			if(style == 'info') {
				this.rightButtonTitle = '�젙蹂�';
			}
		}
	};
	bUIControls.prototype.showNavBar = function() {
		var _myNavBar = '<div id=\'_navbar\' style=\'-webkit-box-sizing: border-box;padding: 0px;height: 44px;background:skyblue;\'>';
		if(this.leftButtonVisible)
		{
			_myNavBar += '<a href=\'javascript:' + this.leftButtonClickJS + '();\' style=\'position:absolute; top:8px; left:10px; right:auto; border-width:0 5px; margin:0; padding:0 3px; width:auto; height:30px; line-height:30px; font-family:inherit; font-size:12px; font-weight:bold; color:#fff; text-shadow:rgba(0, 0, 0, 0.6) 0px -1px 0; text-overflow:ellipsis; text-decoration:none; white-space:nowrap; background:none;\'>'+this.leftButtonTitle+'</a>';
		}
		if(this.rightButtonVisible)
		{
			_myNavBar += '<a href=\'javascript:' + this.rightButtonClickJS + '();\' style = \'position:absolute; top:8px; right: 10px; left: auto; border-width: 0 5px; margin:0; padding:0 3px; width:auto; height:30px; line-height:30px; font-family:inherit; font-size:12px; font-weight:bold; color:#fff; text-shadow:rgba(0, 0, 0, 0.6) 0px -1px 0; text-overflow:ellipsis; text-decoration:none; white-space:nowrap; background:none;\'>'+this.rightButtonTitle+'</a>';
		}
		_myNavBar += '<center><div style=\'padding-top:10px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-align:center; color:#fff; width:45%; font-size:20px; font-weight:bold; text-shadow:rgba(0, 0, 0, 0.6) 0px -1px 0;\'>' + this.navBarTitle + '</div></center>';
		_myNavBar += '</div>';
		document.body.style.margin = '0';
		document.body.innerHTML = _myNavBar + document.body.innerHTML;
	};
	bUIControls.prototype.hideNavBar = function() {
	    iLibropiaApp.exec("UIControls.hideNavBar");
	};
	navigator.browser.uicontrols = new bUIControls();
}

/*
 * app과 web을 연동해주는 js, 안드로이드에서 사용
 */

if(navigator.userAgent.indexOf("ecoweb1.1") != -1) {
	(function() 
	 {
	    var timer = setInterval(function()
		{
			var state = document.readyState;
	        if ( ( state == 'loaded' || state == 'complete' ))
			{
				clearInterval(timer); // stop looking

				// all constructors run, now fire the deviceready event
				var e = document.createEvent('Events');
				e.initEvent('deviceready');
				document.dispatchEvent(e);
			}
	    }, 1);
	})();
}






	//지도
function dMap() {
	this.eleArray = null;
	this.title = '';
	this.useGPS = '1';
	this.center = null;
	this.clickJS = null;
	this.leftButtonVisible = '0';
	this.leftButtonTitle = null;
	this.leftButtonClickJS = null;
	this.rightButtonVisible = '0';
	this.rightButtonTitle = null;
	this.rightButtonClickJS = null;
}
dMap.prototype.createMap = function(eleArray,useGPS,center,clickJS) {
	if(eleArray)
		this.eleArray = eleArray;
	if(useGPS)
		this.useGPS = useGPS;
	if(center)
		this.center = center;
	if(clickJS)
		this.clickJS = clickJS;
};
dMap.prototype.setTitle = function(title) {
	if(title)
		this.title = title;
};
dMap.prototype.setLeftButton = function(isVisible, title, clickJS) {
	if(isVisible)
		this.leftButtonVisible = isVisible;
	if(title)
		this.leftButtonTitle = title;
	if(clickJS)
		this.leftButtonClickJS = clickJS;
};
dMap.prototype.setRightButton = function(isVisible, title, clickJS) {
	if(isVisible)
		this.rightButtonVisible = isVisible;
	if(title)
		this.rightButtonTitle = title;
	if(clickJS)
		this.rightButtonClickJS = clickJS;
};
dMap.prototype.showMap = function() {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.map.show(this.eleArray,this.title,this.useGPS,this.center,this.clickJS,
				this.leftButtonVisible,this.leftButtonTitle,this.leftButtonClickJS,
				this.rightButtonVisible,this.rightButtonTitle,this.rightButtonClickJS);
	} else if(navigator.deviceName == 'androidApp'){
		
		//지도정보, gps사용유무, 중심좌표, clickJS, 제목, 왼쪽버튼활성화,버튼이름,버튼ClickJS,오른버튼 활성화,버튼이름,버튼ClickJS
		window.MapExecuter.show(encodeURIComponent(this.eleArray), this.useGPS, this.center, this.clickJS, this.title, 
				this.leftButtonVisible, this.leftButtonTitle,this.leftButtonClickJS,
				this.rightButtonVisible,this.rightButtonTitle,this.rightButtonClickJS);
	}
};

navigator.map = new dMap();

/**
 * homepage
 */
function dHomepage() {
	
	this.url = null;
	this.title = null;
	this.leftButtonVisible = '0'; 
	this.leftButtonTitle = null;
	this.leftButtonClickJS = null;
	this.rightButtonVisible = '0';
	this.rightButtonTitle = null; 
	this.rightButtonClickJS = null;
	
}

dHomepage.prototype.setUrl = function(url) {
	if(url)
		this.url = url;
};

dHomepage.prototype.setTitle = function(title) {
	if(title)
		this.title = title;
};
dHomepage.prototype.setLeftButton = function(isVisible, title, clickJS) {
	if(isVisible)
		this.leftButtonVisible = isVisible;
	if(title)
		this.leftButtonTitle = title;
	if(clickJS)
		this.leftButtonClickJS = clickJS;
};
dHomepage.prototype.setRightButton = function(isVisible, title, clickJS) {
	if(isVisible)
		this.rightButtonVisible = isVisible;
	if(title)
		this.rightButtonTitle = title;
	if(clickJS)
		this.rightButtonClickJS = clickJS;
};
dHomepage.prototype.showHomePage = function() {
	
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.homepage.show(this.url,this.title,
				this.leftButtonVisible, this.leftButtonTitle, this.leftButtonClickJS,
				this.rightButtonVisible, this.rightButtonTitle, this.rightButtonClickJS);
	} else if (navigator.userAgent.indexOf("ecoweb1.0") != -1) { 
		location.href = "homepage::"+this.url+"||"+this.title;
		
	} else if (navigator.deviceName == 'androidApp') {
		
		window.NewWindowExecuter.show(this.url, this.title, 
				this.leftButtonVisible, this.leftButtonTitle, this.leftButtonClickJS, 
				this.rightButtonVisible, this.rightButtonTitle, this.rightButtonClickJS);
	} else {
		window.open(this.url);
	}
};

navigator.homePage = new dHomepage();

/**
 * email
 */
function dEmail() {
	
	this.emailAddress = '';
}

dEmail.prototype.setEmailAddress = function(emailAddress) {
	if(emailAddress){
		this.emailAddress = emailAddress;
	}
};

dEmail.prototype.showEmail = function(emailAddress) {
	if(emailAddress) {
		this.setEmailAddress(emailAddress);
	}
	if (emailAddress == "") {
		alert('올바르지 않은 이메일 주소입니다.');
		return;
	}
	if (navigator.deviceName == 'iPhoneApp') {
		
		location.href = "mailto:"+this.emailAddress;
		
	} else if (navigator.userAgent.indexOf("ecoweb1.0") != -1) {
		
		location.href = "mailto:"+this.emailAddress;
		
	} else if (navigator.deviceName == 'androidApp') {
		
		window.AppBasicExecuter.showEmailWindow(this.emailAddress);
		
	}
};

navigator.email = new dEmail();

/**
 * phone call
 */

function dPhoneCall() {
	
	this.callNum = '';
}

dPhoneCall.prototype.setCallNum = function(callNum) {
		if(callNum != null && callNum != ""){
			if(callNum.indexOf('~') >= 0){
				var startPoint = callNum.indexOf('~');
				callNum = callNum.substr(0, startPoint);	
			}
			callNum = 'tel:'+callNum;
			this.callNum = callNum;
		}
};

dPhoneCall.prototype.exeCall = function(callNum) {
	if (callNum){
		this.setCallNum(callNum);
	}
	if (callNum == "") {
		alert('올바르지 않은 전화번호입니다.');
		return;
	}
	if (navigator.deviceName == 'iPhoneApp') {
		location.href = this.callNum;
	} else if (navigator.userAgent.indexOf("ecoweb1.0") != -1) {
		location.href = this.callNum;
	} else if (navigator.deviceName == 'androidApp') {
		window.AppBasicExecuter.phoneCall(this.callNum);
	}
};
navigator.phoneCall = new dPhoneCall();

//증강현실
function dARView() {
	this.eleArray = null;
	this.clickJS = null;
	this.userLocation = null;
	this.searchDistance = null;
	this.xmlURL = null;
}
dARView.prototype.create = function(eleArray,clickJS,userLocation,searchDistance, xmlURL) {
	if(eleArray)
		this.eleArray = eleArray;
	else
		return;
	if(clickJS)
		this.clickJS = clickJS;
	if(userLocation)
		this.userLocation = userLocation;
	if(searchDistance)
		this.searchDistance = searchDistance;
	if(xmlURL)
		this.xmlURL = xmlURL;
};
dARView.prototype.show = function() {
	if (navigator.userAgent.indexOf("iPhone") != -1) {
		navigator.ios.arview.show(this.eleArray,this.clickJS,this.userLocation,this.searchDistance, this.xmlURL);
	} else if(navigator.userAgent.indexOf("ecoweb1.1") != -1){
		window.ARExecuter.show(encodeURIComponent(this.eleArray),this.clickJS,this.xmlURL);
	}
};

navigator.arview = new dARView();

//바코드리더
function dBarcodeReader() {
}

dBarcodeReader.prototype.show = function() {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.barcodeReader.readStart('barcodeCallBack','');
	} else if(navigator.deviceName == 'androidApp'){
		window.BarcodeExecuter.barcodeExe();
	}
};

navigator.barcodeReader = new dBarcodeReader();


function dBackButton() {
	this.close_flag = 0;
}
dBackButton.prototype.closeAction = function() {
	if (!this.close_flag) {
		window.BackButtonExecuter.showDialog('한번더 누르시면 종료됩니다.');
		this.close_flag++;
	}
	else {
		window.BackButtonExecuter.closeApplication();
	}
};
navigator.backButton = new dBackButton();

function dNavBar() {
}

dNavBar.prototype.show = function() {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.showNavBar();
	} else if(navigator.deviceName == 'androidApp'){
		window.NaviBarExecuter.show();
	} else {
		navigator.browser.uicontrols.showNavBar();
	}
};
dNavBar.prototype.hide = function() {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.hideNavBar();
	} else if(navigator.deviceName == 'androidApp'){
		window.NaviBarExecuter.hide();
	} else {
		navigator.browser.uicontrols.hideNavBar();
	}
};
dNavBar.prototype.setTitle = function(title) {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.setNavBarTitle(title);
	} else if(navigator.deviceName == 'androidApp'){
		window.NaviBarExecuter.setTitle(title);
	} else {
		navigator.browser.uicontrols.setNavBarTitle(title);
	}
};
dNavBar.prototype.setImage = function( style ) {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.setNavBarImage( style );
	} else if(navigator.deviceName == 'androidApp'){
		/*
		 * Android Code Here!
		 */
	}
};
dNavBar.prototype.setTitleColor = function( color ) {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.setNavBarTextColor( color );
	} else if(navigator.deviceName == 'androidApp'){
		/*
		 * Android Code Here!
		 */
	}
};
dNavBar.prototype.setButtonTitleColor = function( color ) {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.setNavButtonTextColor( color );
	} else if(navigator.deviceName == 'androidApp'){
		/*
		 * Android Code Here!
		 */
	}
};

dNavBar.prototype.setLeftButton = function(isVisible, title, clickJS, style) {
	if(!style)
	{
		style = 'button';
	}
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.setNavBarLeftButton(isVisible, title, clickJS, style);
	} else if(navigator.deviceName == 'androidApp'){
		window.NaviBarExecuter.setLeftButton(isVisible, title, clickJS, style);
	} else {
		navigator.browser.uicontrols.setNavBarLeftButton(isVisible, title, clickJS, style);
	}
};
dNavBar.prototype.setRightButton = function(isVisible, title, clickJS, style) {
	if(!style)
	{
		style = 'button';
	}
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.setNavBarRightButton(isVisible, title, clickJS, style);
	} else if(navigator.deviceName == 'androidApp'){
		window.NaviBarExecuter.setRightButton(isVisible, title, clickJS, style);
	} else {
		navigator.browser.uicontrols.setNavBarRightButton(isVisible, title, clickJS, style);
	}
};
navigator.navBar = new dNavBar();

function dTabBar() {
	this.tabBarTag = 0;
}

dTabBar.prototype.show = function() {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.showTabBar();
	} else if(navigator.deviceName == 'androidApp'){
		window.TabBarExecuter.show();
	}
};
dTabBar.prototype.hide = function() {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.hideTabBar();
	} else if(navigator.deviceName == 'androidApp'){
		window.TabBarExecuter.hide();
	}
};
dTabBar.prototype.addItem = function(title, imageName, linkURL) {
	if (navigator.deviceName == 'iPhoneApp') {
		var itemName = this.tabBarTag++ +'';
		var options = {};
		if(linkURL) {
			options.linkURL = linkURL;
		}
		navigator.ios.uicontrols.createTabBarItem(itemName, title, imageName +'.png', options);
		navigator.ios.uicontrols.showAllTabBarItems();
	} else if(navigator.deviceName == 'androidApp'){
		window.TabBarExecuter.addItem(title, imageName, linkURL);
	}
};
dTabBar.prototype.selectItem = function(num) {
	if (navigator.deviceName == 'iPhoneApp') {
		navigator.ios.uicontrols.selectTabBarItem(num);
	} else if(navigator.deviceName == 'androidApp'){
		window.TabBarExecuter.selectItem(num);
	}
};

navigator.tabBar = new dTabBar();


