(function( window )
{
    if ( window['ACMS'] ) { return false; }

    // parse query
    var elm     = document.getElementById('acms-js');
    var query   = {};
    if ( elm ) {
        var s   = elm.src.split('?');
        if ( 1 < s.length ) {
            var Query   = parseQuery(s[1]);
            for ( key in Query ) {
                query[key]    = Query[key];
            }
        }
    }
    query.searchEngineKeyword = '';
    if ( document.referrer.match(/^http:\/\/www\.google\..*(?:\?|&)q=([^&]+).*$|^http:\/\/search\.yahoo\.co\.jp.*(?:\?|&)p=([^&]+).*$|^http:\/\/www\.bing\.com.*(?:\?|&)q=([^&]+).*$/) ) {
        query.searchEngineKeyword = decodeURIComponent(RegExp.$1 || RegExp.$2 || RegExp.$3).replace(/\+/g, ' ');
    }
    query.root   = '/';
    if ( query.offset ) { query.root += query.offset + '/'; }
    query.jsRoot    = query.root + query.jsDir;
    query.hash      = window.document.location.hash; 

    // include path
    var path    = query.jsRoot;

    // load jquery
    var ajax    = window.navigator.userAgent.match(/MSIE/) ? new ActiveXObject("Msxml2.XMLHTTP") : new XMLHttpRequest();
    ajax.open('get', path + 'library/jquery/jquery-1.4.2.min.js', false);
    ajax.send(null);
    eval(ajax.responseText);

    //--------
    // Config
    var Config  = function( key, value )
    {
        if ( !key ) { return ''; }
        if ( 'string' == typeof(key) ) {
            if ( !value ) {
                return ( 'undefined' != typeof(this.Config[key]) ) ? this.Config[key] : '';
            } else {
                this.Config[key]    = value;
                return true;
            }
        } else {
            for ( _key in key ) { 
                this.Config[_key] = key[_key];
            }
        }
    }

    //----------
    // Dispatch
    var Dispatch    = function ( ) { }

    //---------
    // Library
    var Library = function ( ) { }
    Library.parseQuery  = parseQuery;

    //------
    // Load
    var Load    = function ( url, charset, pre, post )
    {
        url     = ( 'string' == typeof(url) ) ? url : '';
        charset = ( 'string' == typeof(charset) ) ? charset : '';
        pre     = $.isFunction(pre) ? pre : function ( ) { };
        post    = $.isFunction(post) ? post : function ( ) { };
        return function ( load, async )
        {
            if ( !$.isFunction(load) ) { load = function ( ) { }; }
            var self    = arguments.callee;
            if ( !self.executed ) {
                self.executed   = true;
                self.stack      = [load];
                if ( !async ) {
                    ajax.open('get', url, false);
                    ajax.send(null);
                    var data  = ajax.responseText;
                    pre();
                    with ( window ) { eval(data); }
                    post();
                    self.loaded = true;
                    return load();
                } else {
                    pre();
                    $.ajax({
                        'url'           : url,
                        'dataType'      : 'script',
                        'scriptCharset' : charset,
                        'complete'      : function ( )
                        {
                            post();
                            self.loaded = true;
                            while ( self.stack.length ) { 
                                (self.stack.shift())();
                            }
                        }
                    });
                    return true;
                }
            } else {
                if ( self.loaded ) {
                    return load();
                } else {
                    self.stack.push(load);
                    return true;
                }
            }
        }
    }
    Load.Config                     = Load(path + 'config.js');
    Load.Dispatch                   = Load(path + 'dispatch.js');
    Load.Dispatch._static2dynamic   = Load(path + 'dispatch/_static2dynamic.js');
    Load.Dispatch._validate         = Load(path + 'dispatch/_validate.js');
    Load.Dispatch.highslide         = Load(path + 'dispatch/highslide.js');
    Load.Dispatch.ckeditor          = Load(path + 'dispatch/ckeditor.js');
    Load.Dispatch.emoditor          = Load(path + 'dispatch/emoditor.js');
    Load.Dispatch.Utility           = Load(path + 'dispatch/utility.js');
    Load.Dispatch.Postinclude       = Load(path + 'dispatch/postinclude.js');
    Load.Dispatch.Postinclude._postinclude  = Load(path + 'dispatch/postinclude/_postinclude.js');
    Load.Dispatch.Linkmatchlocation = Load(path + 'dispatch/linkmatchlocation.js');
    Load.Dispatch.Admin             = Load(path + 'dispatch/admin.js');
    Load.Dispatch.Admin._tooltip    = Load(path + 'dispatch/admin/_tooltip.js');
    Load.Dispatch.Admin.Configunit  = Load(path + 'dispatch/admin/configunit.js');
    Load.Dispatch.Edit              = Load(path + 'dispatch/edit.js');
    Load.Dispatch.Edit._add         = Load(path + 'dispatch/edit/_add.js');
    Load.Dispatch.Edit._change      = Load(path + 'dispatch/edit/_change.js');
    Load.Dispatch.Edit._emojiedit   = Load(path + 'dispatch/edit/_emojiedit.js');
    Load.Dispatch.Edit._item        = Load(path + 'dispatch/edit/_item.js');
    Load.Dispatch.Edit._tagassist   = Load(path + 'dispatch/edit/_tagassist.js');
    Load.Dispatch.Edit._category    = Load(path + 'dispatch/edit/_category.js');
    Load.Dispatch.Edit.map          = Load(path + 'dispatch/edit/map.js');
    Load.Library                    = Load(path + 'library.js');
    Load.Library.validator          = Load(path + 'library/validator.js');
    Load.Library.highslide          = Load(path + 'library/highslide/highslide.js', null, null, function ( ) { ACMS.Dispatch._highslideInit(); })
    Load.Library.swfobject          = Load(path + 'library/swfobject/swfobject.js');
    Load.Library.ckeditor           = Load(path + 'library/ckeditor/ckeditor.js', null, function ( ) { ACMS.Dispatch._ckeditorPre(); }, function ( ) { ACMS.Dispatch._ckeditorPost(); });
    Load.Library.Jquery             = {};
    Load.Library.Jquery.biggerlink  = Load(path + 'library/jquery/jquery.biggerlink.min.js');
    Load.Library.Jquery.cookie      = Load(path + 'library/jquery/jquery.cookie.js');
    Load.Library.Jquery.selection   = Load(path + 'library/jquery/jquery.selection.js');
    Load.Library.Jquery.Ui          = {};
    Load.Library.Jquery.Ui.core     = Load(path + 'library/jquery/ui/jquery.ui.core.min.js', null, function ( )
    {
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.theme.css" />');
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.core.css" />');
    });
    Load.Library.Jquery.Ui.widget   = Load(path + 'library/jquery/ui/jquery.ui.widget.min.js', null, function () {
        ACMS.Load.Library.Jquery.Ui.core();
    });
    Load.Library.Jquery.Ui.mouse    = Load(path + 'library/jquery/ui/jquery.ui.mouse.min.js');
    Load.Library.Jquery.Ui.position = Load(path + 'library/jquery/ui/jquery.ui.position.min.js');
    Load.Library.Jquery.Ui.draggable= Load(path + 'library/jquery/ui/jquery.ui.draggable.min.js', null, function ( ) {
        ACMS.Load.Library.Jquery.Ui.mouse();
    });
    Load.Library.Jquery.Ui.resizable= Load(path + 'library/jquery/ui/jquery.ui.resizable.min.js', null, function ( ) {
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.resizable.css" />');
        ACMS.Load.Library.Jquery.Ui.mouse();
    });
    Load.Library.Jquery.Ui.sortable = Load(path + 'library/jquery/ui/jquery.ui.sortable.min.js', null, function ( ) {
        ACMS.Load.Library.Jquery.Ui.mouse();
    });
    Load.Library.Jquery.Ui.accordion= Load(path + 'library/jquery/ui/jquery.ui.accordion.min.js', null, function ( )
    {
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.accordion.css" />');
    });
    Load.Library.Jquery.Ui.button   = Load(path + 'library/jquery/ui/jquery.ui.button.min.js', null, function ( )
    {
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.button.css" />');
    });
    Load.Library.Jquery.Ui.dialog   = Load(path + 'library/jquery/ui/jquery.ui.dialog.min.js', null, function ( )
    {
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.dialog.css" />');
        ACMS.Load.Library.Jquery.Ui.draggable();
        ACMS.Load.Library.Jquery.Ui.resizable();
        ACMS.Load.Library.Jquery.Ui.button();
    });
    Load.Library.Jquery.Ui.tabs     = Load(path + 'library/jquery/ui/jquery.ui.tabs.min.js', null, function ( )
    {
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.tabs.css" />');
    });
    Load.Library.Jquery.Ui.datepicker   = Load(path + 'library/jquery/ui/jquery.ui.datepicker.min.js', null, function ( )
    {
        $('head').append('<link type="text/css" rel="stylesheet" href="' + ACMS.Config.jsRoot + 'library/jquery/ui/css/' + ACMS.Config.uiTheme + '/jquery.ui.datepicker.css" />');
        ACMS.Load.Library.Jquery.Ui.core();
    });
    Load.Library.google             = Load(window.location.protocol + '//www.google.com/jsapi?key=' + query.googleApiKey);

    //------
    // ACMS
    var ACMS    = function ( ) { }

    //----------
    // register
    ACMS.Config     = Config;
    ACMS.Load       = Load;
    ACMS.Dispatch   = Dispatch;
    ACMS.Library    = Library;
    window.ACMS     = ACMS;

    //--------
    // define
    define('ACMS.Dispatch', Load.Dispatch);
    define('ACMS.Dispatch._tagassist', Load.Dispatch._tagassist);
    define('ACMS.Dispatch._static2dynamic', Load.Dispatch._static2dynamic);
    define('ACMS.Dispatch._validate', Load.Dispatch._validate);
    define('ACMS.Dispatch._highslideInit', Load.Dispatch.highslide);
    define('ACMS.Dispatch._ckeditorPre', Load.Dispatch.ckeditor);
    define('ACMS.Dispatch._ckeditorPost', Load.Dispatch.ckeditor);
    define('ACMS.Dispatch.highslide', Load.Dispatch.highslide);
    define('ACMS.Dispatch.ckeditor', Load.Dispatch.ckeditor);
    define('ACMS.Dispatch.emoditor', Load.Dispatch.emoditor);
    define('ACMS.Dispatch.Utility', Load.Dispatch.Utility);
    define('ACMS.Dispatch.Postinclude.ready', Load.Dispatch.Postinclude);
    define('ACMS.Dispatch.Postinclude.submit', Load.Dispatch.Postinclude);
    define('ACMS.Dispatch.Postinclude._postinclude', Load.Dispatch.Postinclude._postinclude);
    define('ACMS.Dispatch.Linkmatchlocation.part', Load.Dispatch.Linkmatchlocation);
    define('ACMS.Dispatch.Linkmatchlocation.full', Load.Dispatch.Linkmatchlocation);
    define('ACMS.Dispatch.Linkmatchlocation.blog', Load.Dispatch.Linkmatchlocation);
    define('ACMS.Dispatch.Linkmatchlocation.category', Load.Dispatch.Linkmatchlocation);
    define('ACMS.Dispatch.Linkmatchlocation.entry', Load.Dispatch.Linkmatchlocation);
    define('ACMS.Dispatch.Admin', Load.Dispatch.Admin);
    define('ACMS.Dispatch.Admin._tooltip', Load.Dispatch.Admin._tooltip);
    define('ACMS.Dispatch.Admin.Configunit', Load.Dispatch.Admin.Configunit);
    define('ACMS.Dispatch.Admin.Configunit._add', Load.Dispatch.Admin.Configunit);
    define('ACMS.Dispatch.Admin.Configunit.remove', Load.Dispatch.Admin.Configunit);
    define('ACMS.Dispatch.Edit', Load.Dispatch.Edit);
    define('ACMS.Dispatch.Edit._add', Load.Dispatch.Edit._add);
    define('ACMS.Dispatch.Edit._change', Load.Dispatch.Edit._change);
    define('ACMS.Dispatch.Edit._emojiedit', Load.Dispatch.Edit._emojiedit);
    define('ACMS.Dispatch.Edit._item', Load.Dispatch.Edit._item);
    define('ACMS.Dispatch.Edit._tagassist', Load.Dispatch.Edit._tagassist);
    define('ACMS.Dispatch.Edit._category', Load.Dispatch.Edit._category);
    define('ACMS.Dispatch.Edit.updatetime', Load.Dispatch.Edit);
    define('ACMS.Dispatch.Edit.map', Load.Dispatch.Edit.map);
    define('ACMS.Library.scrollTo', Load.Library);
    define('ACMS.Library.scrollToElm', Load.Library);
    define('ACMS.Library.dl2object', Load.Library);
    define('ACMS.Library.getPostData', Load.Library);
    define('ACMS.Library.acmsLink', Load.Library);
    define('ACMS.Library.Validator.isFunction', Load.Library.validator);
    define('hs.expand', Load.Library.highslide, true);
    define('swfobject.embedSWF', Load.Library.swfobject, true);
    define('CKEDITOR.replace', Load.Library.ckeditor, true);
    define('jQuery.widget', Load.Library.Jquery.Ui.widget);
    define('jQuery.fn.position', Load.Library.Jquery.Ui.position);
    define('jQuery.fn.sortable', Load.Library.Jquery.Ui.sortable);
    define('jQuery.fn.accordion', Load.Library.Jquery.Ui.accordion);
    define('jQuery.fn.tabs', Load.Library.Jquery.Ui.tabs);
    define('jQuery.fn.dialog', Load.Library.Jquery.Ui.dialog);
    define('jQuery.fn.datepicker', Load.Library.Jquery.Ui.datepicker);
    define('jQuery.cookie', Load.Library.Jquery.cookie);
    define('jQuery.fn.biggerlink', Load.Library.Jquery.biggerlink);
    define('jQuery.fn.selection', Load.Library.Jquery.selection);
    define('google.load', Load.Library.google, false, true);

    //-------------
    // Load config
    $.each(query, function ( key ) { ACMS.Config[key] = this; });
    Load.Config();

    function parseQuery ( query )
    {
        var s   = query.split('&');
        var data    = {};
        for ( var i=0; i<s.length; i++ ) {
            var param   = s[i].split('=');
            if ( 'undefined' == typeof(param[0]) ) { continue; }
            var key     = param[0];
            var value   = ('undefined' != typeof(param[1])) ? param[1] : key;
            data[key]   = decodeURIComponent(value);
        }
        return data;
    }

    function define ( name, load, del, async )
    {
        var objname = 'window';
        $.each(name.split('.'), function ( i )
        {
            objname += ('.' + this);
            if ( 'undefined' == eval('typeof ' + objname) ) { eval(objname + '={};'); }
        });

        //-------
        // proxy
        this['proxy'] = function ( )
        {
            var scope       = this;
            var args        = arguments;
            var placeholder = arguments.callee;
            if ( del ) { window[name.replace(/\..*$/, '')] = undefined; }
            return load(function ( )
            {
                try {
                    var func    = eval(name);
                } catch ( e ) {
                    return false;
                }
                if ( 'function' != typeof(func) ) { return false; }
                if ( func == arguments.callee ) { return false; }

                //--------------------
                // take over property
                for ( key in placeholder ) {
                    if ( func[key] ) {
                        for ( _key in placeholder[key] ) {
                            func[key][_key] = placeholder[key][_key];
                        }
                    } else {
                        func[key] = placeholder[key];
                    }
                }

                return func.apply(scope, args);
            }, async);
        }
        eval(name+"=this['proxy']");
    }

})(window);

//-------
// ready
$(function ( )
{
    ACMS.Dispatch(document);
});
