var View = function(type){

    this.width = 19
    this.blocks = {}
    this.columnSetN = 0
    this.columnSets = null
    this.userSetIndex = -1
    this.captions = []
    this.currBlocksRendered = 12
    this.x = 0 //0..width - groupLength
    this.menu = null
    this.type = type
    this.allSetN = 0
    this.event = null
    
    var ChannelLoadedListener = {
        exec : function(eventSource, params, request){

        	if (!request.responseXML) return;

        	var block
        	var caption
        	var i = 0
        	for (var e=request.responseXML.documentElement.firstChild; e && i<2; e = e.nextSibling){
	            if (e.nodeType == 1 && e.tagName.toLowerCase() == 'description'){
    	        	caption = e
        	    	i++
        		} else
        		if (e.nodeType == 1 && e.tagName.toLowerCase() == 'li'){
            		block = e
            		i++
        		}
        	}

        	caption.parentNode.removeChild(caption)

        	var targetBlock = eventSource.blocks[params.blockN + '' + params.allColumnN]['html']
        	var label = block.getElementsByTagName('label')[0]
        	var labelValue = label.firstChild.nodeValue
        	var updated = (labelValue != eventSource.blocks[params.blockN + '' + params.allColumnN]['label'])
        	
        	//$('print').value += labelValue +' : '+eventSource.blocks[params.blockN + '' + params.allColumnN]['label']+'\r'
        	eventSource.blocks[params.blockN + '' + params.allColumnN]['label'] = labelValue
        	block.removeChild(label)
        	if (updated) targetBlock.innerHTML = Loader.serialize(block)
        	
        	var captionLI
        	if (params.insertCaption) {
	        	captionLI = caption.getElementsByTagName('li')[0]
	        	with (eventSource.captions[params.allColumnN]){
	            	innerHTML = Loader.serialize(captionLI)
	            	className = captionLI.getAttribute('class')
	        	}
        	} 
            
            Mediator.notify(View.CONTENT_CHANGED, this, {block : targetBlock})    
                
        	if (eventSource.menu.permutationBlocks[params.allColumnN]){
            	for (var permutationChannel in eventSource.menu.permutationBlocks[params.allColumnN]){
                	var pBlock = eventSource.menu.permutationBlocks[params.allColumnN][permutationChannel][params.blockN]
                	pBlock.innerHTML = targetBlock.innerHTML
                	Mediator.notify(View.CONTENT_CHANGED, this, {block : pBlock})
                	if (params.insertCaption) {
                    	with (eventSource.menu.permutationCaptions[params.allColumnN][permutationChannel]){
                    		innerHTML = eventSource.captions[params.allColumnN].innerHTML
                        	className = captionLI.getAttribute('class')
                    	}
                	}
            	}

			}
	    }
    }
    
    
    function cloneProtoBlock(){
    	var block = $('protoBlock').cloneNode(true);
        block.removeAttribute('id')
        block.style.display = 'block'
        return block
    }

    this.init = function() {
        this.userSetIndex = Settings.channelSets.length
        this.columnSetN = Settings.defaultSetN
        this.columnSets = Settings.channelSets
        this.width = Settings.channelSets[this.columnSetN].length
        this.allSetN = Settings.allSetN
        this.event = Mediator.LOAD_CHANNEL

        TVProgram.addListener(Mediator.LOAD_CHANNEL, ChannelLoadedListener)
        TVProgram.addListener(Mediator.LOAD_GENRE, ChannelLoadedListener)
    }

    this.getBlock = function(blockN, columnN) {
        var allColumnN = (this.columnSetN == this.allSetN) ? columnN : this.columnSets[this.columnSetN][columnN]
        var block = null

        var channelId = this.columnSets[this.allSetN][allColumnN]
        var localBlockN = blockN % Settings.blocksCount + 1
        var label = 0

        if (!this.blocks[blockN + '' + allColumnN] || TVProgram.oldY - blockN > 1) {
            block = cloneProtoBlock()
            this.blocks[blockN + '' + allColumnN] = {}
            this.blocks[blockN + '' + allColumnN]['html'] = block

            if (this.menu.permutationBlocks[allColumnN]) {
                for (var pChannel in this.menu.permutationBlocks[allColumnN]) {
                    if (this.menu.permutationBlocks[allColumnN][pChannel][blockN]) break
                    block = cloneProtoBlock()
                    this.menu.permutationBlocks[allColumnN][pChannel][blockN] = block
                }
            }

	    	Loader.load(this.event, this, 
	    	            {blockN : blockN, allColumnN : allColumnN, columnN : columnN, 
	    	            	insertCaption : (blockN == TVProgram.y)},
                        {id : channelId, blockN : blockN, week1 : TVProgram.weekN, 
                        	day : Math.floor(blockN / Settings.blocksCount) % 7 + 1, 
                        	block : localBlockN, label : this.blocks[blockN + '' + allColumnN]['label']})

        }

        if (this.columnSetN == this.userSetIndex && this.menu.permutationBlocks[allColumnN] && this.menu.permutationBlocks[allColumnN][columnN]) {
            block = this.menu.permutationBlocks[allColumnN][columnN][blockN]
        } else {
            block = this.blocks[blockN + '' + allColumnN]['html']
        }
		        
        return block
    }
    
    this.getCaption = function(columnN) {
        var allColumnN = (this.columnSetN == this.allSetN) ? columnN : this.columnSets[this.columnSetN][columnN]
        var caption = null

        if (!this.captions[allColumnN]) {
            caption = $('protoCaption').cloneNode(true);
            caption.removeAttribute('id')
            this.captions[allColumnN] = caption
            caption.style.display = 'block'
        }

        if (this.columnSetN == this.userSetIndex && this.menu.permutationCaptions[allColumnN] && (caption = this.menu.permutationCaptions[allColumnN][columnN]));
        else caption = this.captions[allColumnN]

        return caption
    }

    this.loadBlocks = function(columnN, count, yDirection) {
        if (TVProgram.y + yDirection < 0 || TVProgram.y + yDirection >= TVProgram.height) return
        if (columnN < this.oldX) {
            var firstChannel = TVProgram.tvPrograms[yDirection + 1].firstChild
            var firstCaption = TVProgram.tvCaptions.firstChild
            for (var i = (columnN < 0) ? 0 : columnN; i < columnN + count && i < this.width; i++) {
                if (yDirection == 0) {
                    TVProgram.tvCaptions.insertBefore(this.getCaption(i), firstCaption)
                    this.currBlocksRendered++
                }

                TVProgram.tvPrograms[yDirection + 1].insertBefore(this.getBlock(TVProgram.y + yDirection, i), firstChannel)
            }
        } else {
            for (var i = (columnN < 0) ? 0 : columnN; i < columnN + count && i < this.width; i++) {
                if (yDirection == 0) {
                    TVProgram.tvCaptions.appendChild(this.getCaption(i))
                    this.currBlocksRendered++
                }
                TVProgram.tvPrograms[yDirection + 1].appendChild(this.getBlock(TVProgram.y + yDirection, i))
            }
        }
    }

    this.changeSet = function() {
    	TVProgram.scroll.menuPos = TVProgram.scroll.scrollHeight
    	$('bottomMenus1').scrollTop = 0
        this.x = this.oldX = 0
        this.currBlocksRendered = 0
        for (var i = 0; i < 3; clear(TVProgram.tvPrograms[i++]));
        clear(TVProgram.tvCaptions)

        this.columnSetN = $('channelSets').selectedIndex
        this.width = this.columnSets[this.columnSetN].length

        if (TVProgram.y > TVProgram.minY) this.loadBlocks(0, TVProgram.groupLength * 2, -1)
        this.loadBlocks(0, TVProgram.groupLength * 2, 0)
        if (TVProgram.y < TVProgram.height - 1) this.loadBlocks(0, TVProgram.groupLength * 2, 1)

        Mediator.notify(Mediator.END_MOVE_SETKA, this)
        Mediator.notify(View.CONTENT_CHANGED, this)
        TVProgram.setupButtons();
    }
}

View.BLOCK_OBTAINED = 'block_obtained'
View.CONTENT_CHANGED = 'block_updated'

var channelsView = new View(TVProgram.CHANNELS)
var genresView = new View(TVProgram.GENRES)
genresView.init = function() {

    genresView.userSetIndex = 1
    genresView.columnSetN = 0
    genresView.columnSets = []
    genresView.channelSetN = channelsView.columnSetN
    genresView.columnSets[0] = Settings.genres
    genresView.width = Settings.genres.length
    genresView.allSetN = 0
    genresView.event = Mediator.LOAD_GENRE


    //var style = document.styleSheets[0]
    var style
    

for (var i=0, ds=document.styleSheets, ilen=ds.length; i<ilen; i++){
	if (ds[i] && ds[i].href && ds[i].href.indexOf('url_filter.css') != -1) {
		style=ds[i]
		break         
	}
}

    if (!style) {
    	throw "Can't determine styleSheet object for url_filter.css"
    }

    var rules = style.cssRules || style.rules
/*
    for (var i=0, ilen=channelsView.columnSets[channelsView.allSetN].length; i<ilen; i++){
        if (style.insertRule) style.insertRule('ul.filter' + i + ' {' + 'display:block;' + '}', i)
        else
        if (style.addRule) style.addRule('ul.filter' + i, 'display:block;', i)
    }
*/
    this.style = style

}

genresView.changeSet = function(){
    var channelSetN = $('channelSets').selectedIndex
var style= genresView.style
/*
    var rules = style.cssRules || style.rules
    for (var i=0, ilen=channelsView.columnSets[channelsView.allSetN].length; i<ilen; i++){
        if (style.insertRule) style.insertRule('ul.filter' + i + ' {' + 'display:block;' + '}', i)
        else
        if (style.addRule) style.addRule('ul.filter' + i, 'display:block;', i)
    }
*/

    var inds = {}
    var rules = genresView.style.cssRules || genresView.style.rules
    for (var i=0, set=channelsView.columnSets[channelSetN], ilen=set.length; i<ilen; i++){
        var channelN = (channelSetN == channelsView.allSetN) ? i : set[i]
        if (!inds[channelN] && rules[channelN].style.display != 'block') rules[channelN].style.display = 'block'
        inds[channelN] = 1
    }
    for (var i=0, set=channelsView.columnSets[channelsView.allSetN], ilen=set.length; i<ilen; i++){
//        if (!rules[i]) break
        if (!inds[i] && rules[i].style.display != 'none') rules[i].style.display = 'none'
    }

//if (document.body.currentStyle) for (var i=0, ilen=3; i<ilen; TVProgram.tvPrograms[i++].innerHTML += '');
if (document.body.currentStyle)
    for (var i=0, ilen=3; i<ilen; i++){
        for (var j=0, timeblocks=TVProgram.tvPrograms[i].childNodes, jlen=timeblocks.length; j<jlen; j++){
            if (timeblocks[j].nodeType==1) timeblocks[j].innerHTML += ''
        }
    }
                                    
    TVProgram.setupButtons();
    Mediator.notify(View.CONTENT_CHANGED, this)
}