var core = {};

core.tpl = function(tpl, dict)
{
    for (var key in dict)
    {
        tpl = tpl.split('{' + key + '}').join(dict[key]);
    }
    return tpl;
};

/*
    global event manager
*/
var _events = function()
{
    this.listeners = {};
    this.init();
    return this;
};

_events.prototype = 
{
    init: function()
    {
    },
    
    fire: function(name, params)
    {
        if (!(name in this.listeners))
        {
            return;
        }
        
        var listener = this.listeners[name];
        var handler;
        for (var i = 0, l = listener.length; i < l; i++)
        {
            handler = listener[i];
            handler.fn.apply(handler.ctx, [params]);
        }
    },
    
    subscribe: function(name, cBack)
    {
        if ( !this.listeners[name] )
        {
            this.listeners[name] = [];
        }
        
        this.listeners[name].push( cBack );
    },
    
    unsubscribe: function(name, cBack)
    {
        if (!(name in this.listeners))
        {
            return;
        }
        
        var listener = this.listeners[name];
        var handler;
        var new_handlers = []
        for (var i = 0, l = listener.length; i < l; i++)
        {
            handler = listener[i];
            // this going to be so sloooow
            // TODO: rewrite with generated IDs
            if (handler.fn != cBack.fn)
            {
                new_handlers.push = handler;
            }
        }
        this.listeners[name] = new_handlers;
    },

    /* wrapper for jQ bind: binds with context */
    bind: function(selector, type, cBack)
    {
        $(selector).bind( type, function(evt) { cBack.fn.apply(cBack.ctx, [evt, this]) } );
    },

    /* wrapper for jQ live: binds live events with context */
    live: function(selector, type, cBack)
    {
        $(selector).live( type, function(evt) { cBack.fn.apply(cBack.ctx, [evt, this]) } );
    }
};

core.events = new _events();

function _console()
{
    this._log = []
    this.init();
    return this;
};

_console.prototype = 
{
    init: function()
    {
        
    },
    
    log: function()
    {
        if (this._log.length < 100)
        {
            this._log.push(arguments.join(', '));
        }
    },
    
    flush: function()
    {
        if (typeof console != 'undefined')
        {
            console.log.apply(window, this._log);
        }
        else if (window.opera)
        {
             window.opera.postError.apply(window.opera, [this._log.join(', ')]);
        }
        this._log = []
    }
};

core.console = new _console();

function _oda(components)
{
    this.components = {};
    this.init(components);
    
    this.events = new _events();
    
    return this;
};

_oda.prototype = 
{
	init: function(components)
    {
        for (var comp in components)
        {
			if (components[comp].name)
			{
				this.addComponent(components[comp].name, components[comp].klass);
			}
        }
    },
    
    addComponent: function(name, klass)
    {
        this.components[name] = new klass();
    }
}

function _modalizer()
{
    this.active = false;
    this.init();
    return this;
};

_modalizer.prototype =
{
    init: function()
    {
        this.shade = $('.js-modalizer');
        this.active = false;

        //core.events.bind(this.shade, 'click', {fn: function() {console.log('fired'); core.events.fire('close_modals'); this.hide();}, ctx: this })
    },

    show: function()
    {
        this.shade.removeClass('g-hidden');
        this.active = true;
    },

    hide: function()
    {
        this.shade.addClass('g-hidden');
        this.active = false;
    },

    isActive: function()
    {
        return this.active;
    }
}

function gallery()
{
    this.dlg = new modal_component('.js-gallerycomp');
    this.gallery = $('.js-gallery-list');

    this.holster = $('.js-gallery');
    this.frame = this.holster.find('.js-gallery-frame');
    this.backstage = this.holster.find('.js-gallery-backstage');
    this.loader = this.holster.find('.js-gallery-loader');
    this.currentPic = this.frame.find('img.js-gallery-current')[0];

    this.middlePic = $('.js-gallery-middlepic');
    this.isMiddlePic = false;

    this.imagesUrl = [];
    this.currentImg = 0;
    this.init();
}

gallery.prototype = 
{
    init: function()
    {
        core.events.subscribe('gallery.preloaded', {fn: this.showBySrc, ctx: this});
        core.events.subscribe('modalcomp.hided', {fn: function(){this.isMiddlePic = false}, ctx: this });
        
        if (this.currentPic)
        {
            core.events.bind(this.currentPic, 'click', {fn: this.onCurrentPicClick, ctx: this});
        }

		/*	Средняя картинка	*/
        core.events.bind(this.middlePic, 'click', {fn: this.showMiddlePic, ctx: this});
        
        var _links = this.gallery.find('a');
        for (var i = 0, l = _links.length; i < l; i++)
        {
            this.imagesUrl.push({src: _links[i].href, cached: false});
        }
        
		/* Мелкие картинки	*/
        core.events.bind(this.gallery, 'click', {fn: this.show, ctx: this});
        
    },

    onCurrentPicClick: function(evt, elm)
    {
        if (!this.isMiddlePic)
        {
            this.scroll(false);
        }

        evt.stopPropagation();
        evt.preventDefault();
        return false;
    },

    show: function(evt, elm)
    {
        var trgt = $(evt.target).parents('a');
        if (!trgt.length) // it may be click on 'li' element
        {
            trgt = $(elm).find('a');
        }
        var src = trgt.attr('href');

        this.currentPic.src = '/media/picts/white-pixel.gif';
        this.currentPic.width = 300;
        
        // detect current index
        for (var idx = 0, l = this.imagesUrl.length; idx < l; idx++)
        {
            if (this.imagesUrl[idx].src.indexOf(src) > -1)
            {
                this.currentImg = idx;
            }
        }

        this.dlg.__show__();
        this.showById(this.currentImg);

        evt.stopPropagation();
        evt.preventDefault();
        return false;
    },

    showMiddlePic: function(evt, elm)
    {
        this.isMiddlePic = true;
        this.loaderStart();
        this.createPreloader( elm.href );

        this.dlg.__show__();

        evt.stopPropagation();
        evt.preventDefault();
        return false;
    },
    
    scroll: function(toLeft)
    {
        if (toLeft)
        {
            if (this.currentImg == 0)
            {
                return false;    
            }
            this.currentImg--;
        }
        else
        {
            if (this.currentImg == this.imagesUrl.length - 1)
            {
                return false;
            }
            this.currentImg++;
        }
        this.showById(this.currentImg);
    },
    
    showById: function(id)
    {
        this.currentImg = id;
        
        if (this.imagesUrl[id].cached)
        {
            this.showBySrc(this.imagesUrl[id].src);
        }
        else
        {
            this.loaderStart();
            this.createPreloader( this.imagesUrl[this.currentImg].src );
        }
    },
    
    showBySrc: function(src)
    {
        this.loaderStop();
        $(this.currentPic).removeAttr('width');
        this.currentPic.src = src;
		if (!this.isMiddlePic)
		{
			this.imagesUrl[this.currentImg].cached = true;	
		}
    },

    createPreloader: function(src)
    {
        var data =
        {
            src: src,
            onload: "core.events.fire('gallery.preloaded', this.src)"
        }
        this.backstage.html( core.tpl('<img src="{src}" onload="{onload}" width="1" height="1"/>', data) );
    },
    
    loaderStart: function()
    {
        this.loader.removeClass('g-hidden');
    },
    
    loaderStop: function()
    {
        this.loader.addClass('g-hidden');
    }
}

function video()
{
    this.playerid = 'oda_player';
    this.dlg = new modal_component('.js-playercomp');

    this.init();

    return this;
}

video.prototype =
{
    init: function()
    {
        this.listing = $('.js-video-list');
        this.cradle = $('.js-player-cradle');

        core.events.bind(this.listing, 'click', {fn: this.show, ctx: this});
    },

    initPlayer: function(url)
    {
        var flashvars =
        {
            "m":    "video",
            'file': url,
            "uid":  this.playerid,
            'st':   '01ARzksQ3Q3QB3Q31la1k0nTnWwjG3kNkbk12LFdwbfzkOk4AdGIF3K1X1SGifzkOkT03whT631X1ke06Q3QRIzd5cYzsNcYfB5XT23G3TSQQD6dwf9F3NXRk3GXe2bwITWwZWTCwXRFWs6If2McTS3QD6dwaXisNXdHms6IN2McTfeMjF3NQXisNXYHv1l1bf0XR3k0cLWwkjzC5ke7jYJc3COf1knOkZ2M8JzC5kS42Qi6R3Gktjd1ozfUrY'
        };
        var params =
        {
            id:                 this.playerid,
            bgcolor:            "#ffffff",
            allowFullScreen:    "true",
            allowScriptAccess:  "always"
        };
        new swfobject.embedSWF("/media/swf/uppod.swf", this.playerid, "500", "375", "9.0.115", false, flashvars, params);
    },


    show: function(evt, elm)
    {
        var trgt = $(evt.target).parents('a');
        if (!trgt.length) // it may be click on 'li' element
        {
            return false;
        }
        var url = trgt.attr('href');

        this.dlg.__show__();

        this.initPlayer(url);
        this.cradle.removeClass('g-hidden');

        evt.stopPropagation();
        evt.preventDefault();
        return false;
    },

    hide: function()
    {
        this.cradle.addClass('g-hidden');
        uppodSend(this.playerid, 'stop');
    }
}

function search_placeholder()
{
    this.init();
    return this;
}
search_placeholder.prototype =
{
    init: function()
    {
        this.field = $('.js-placeholder-field');
        this.placeholder = $('.js-placeholder-label');

        core.events.bind(this.field, 'focus', {fn: this.hide, ctx: this});
        core.events.bind(this.field, 'blur', {fn: this.show, ctx: this});

        if(this.field.val() != '')
        {
            this.hide();
        }
    },
    hide: function(evt, elm)
    {
        this.placeholder.addClass('g-hidden');
    },
    show: function(evt, elm)
    {
        if (this.field.val() == '')
        {
            this.placeholder.removeClass('g-hidden');
        }
    }
}

function modal_component(element)
{
    this.windowedClass = '';
    this.__init__(element);
    return this;
}
modal_component.prototype =
{
    __init__: function(element)
    {
        this.window = $(element);
        this.closeBtn = this.window.find('.js-modalcomp-closebtn');
        core.events.bind(this.closeBtn, 'click', {fn: this.__close__, ctx: this});
        core.events.bind(document, 'keypress', {fn: this.__onkeypress__, ctx: this});

        core.events.bind(this.window, 'click', {fn:this.__close__, ctx: this});
    },

    __show__: function()
    {
        if (core.modalizer.isActive())
        {
            return false;
        }
        core.modalizer.show();
        this.window.addClass(this.windowedClass).removeClass('g-hidden');
        return true;
    },

    __hide__: function()
    {
        if (!core.modalizer.isActive)
        {
            return false;
        }
        this.window.removeClass(this.windowedClass).addClass('g-hidden');
        core.modalizer.hide();
        core.events.fire('modalcomp.hided');
        return true;
    },

    __close__: function(cBack)
    {
        this.__hide__();
    },

    __onkeypress__: function(evt, elm)
    {
        if (evt.keyCode == 27 && !this.window.hasClass('g-hidden'))
        {
            this.__close__();
        }
    }
}


var oda;
$(
    function(){
        core.modalizer = new _modalizer();
        oda = new _oda([
            {name: 'gallery', klass: gallery},
            {name: 'video', klass: video},
            {name: 'placeholder', klass: search_placeholder}
        ])
    }
)
