(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    = ( /*@cc_on!@*/false ) ? 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 ( ) { }
    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(path + 'library/jquery/ui/jquery-ui-1.8.custom.min.js', null, function ( ) { ACMS.Dispatch._uiInit(); });
    Load.Library.google             = load(window.location.protocol + '//www.google.com/jsapi?key=' + query.googleApiKey);

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

    //--------
    // regist
    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._uiInit', Load.Dispatch);
    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.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.fn.datepicker', Load.Library.Jquery.ui);
    define('jQuery.fn.sortable', Load.Library.Jquery.ui);
    define('jQuery.fn.accordion', Load.Library.Jquery.ui);
    define('jQuery.fn.tabs', Load.Library.Jquery.ui);
    define('jQuery.fn.dialog', Load.Library.Jquery.ui);
    define('jQuery.fn.position', Load.Library.Jquery.ui);
    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(null, true);

    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 load ( 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, sync )
        {
            if ( !$.isFunction(load) ) {
                load    = function ( ) { };
            }
            var self    = arguments.callee;
            if ( !self.executed ) {
                self.executed   = true;
                self.stack      = [load];
                if ( sync ) {

                    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);
                }
            }
        }
    }

    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 old     = 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;
                }

                //---------
                // inherit
                for ( key in old ) {
                    if ( !func[key] ) {
                        func[key]   = old[key];
                    } else {
                        var _old    = old[key];
                        for ( _key in _old ) {
                            func[key][_key] = _old[_key];
                        }
                    }
                }

                return func.apply(scope, args);

            }, async ? false : true);
        }
        eval(name+"=this['proxy']");
    }

})(window);

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