<!doctype html>
<head>
<title>looping</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>

var game = {};

game.tFPS = 60;
game.fps = {
	frames: 0,
	lastTime: 0,
	updateTime: 0,
	fps:0,
	set: function() {this.fps=this.frames}
};

game.stats = {
  level : 1,
  clicks: 0,
  stTime: 0,
  time  : 0,
};

game.version = "v.0.2.12:";

game.filesystem = {
	save : function() {
		var data = game;
		localStorage[game.version] = JSON.stringify(data);
	},
	load : function() {
		if (localStorage[game.version]==null) { 
			console.log("No save data found for this version of the game");
		} else {
			var temp = $.parseJSON(localStorage[game.version]);
			
			for(var i=0;i<game.upgrades.length; i++) {
				$.extend(true, game.upgrades[i], temp.upgrades[i]);
			}
			
			$.extend(game.inv.chips, temp.inv.chips);
			$.extend(game.inv.pc, temp.inv.pc);
			for(var i=0;i<game.inv.items.length; i++) {
				$.extend(true, game.inv.items[i], temp.inv.items[i]);
			}
			for(var i=0;i<game.inv.workers.length; i++) {
				$.extend(true, game.inv.workers[i], temp.inv.workers[i]);
			}
			game.stats.level=temp.stats.level;
		}
	}
};

game.prestige = {
  level : 1,
};

game.achievement = function(vars) {
	
}

game.achievements = [
	
]

game.upgrade = function(vars) {
	this.invisible = vars.invisible || true
	this.baseUses = vars.uses || 1;
	this.uses = this.baseUses;
	this.level = vars.level || 0;
	this.cost = vars.cost || 0;
	this.name = vars.name || "upgradeXXX";
	this.run = vars.run || null;
	this.clicks = vars.clicks || 0;
	this.time = vars.time || 0;
	this.pcs = vars.pcs || 0;
	this.desc = vars.desc || 'An upgrade';
	this.reset = function(mode) {
	    this.uses = this.baseUses;
	    this.invisible = true;
	};
	this.update = function() {
	   this.invisible = true;
	   if(this.uses>0) {
	     if (game.stats.level >= this.level) {
	     if (game.stats.clicks>=this.clicks) {
	     if (game.stats.time>=this.time) {
	     if (game.inv.pc.quantity>=this.pcs) {
	         this.invisible=false;
	     }
	     }
	     }
	     }
	  };
	   
	};
	this.use = function() {
		if (game.inv.chips.quantity >= this.cost && this.uses>0) {
			game.inv.chips.quantity -= this.cost;
			this.run(); this.uses --;
		}
		if (this.uses<=0) {this.invisible = true; console.log('this should be hiding now..')};
	};
};

game.upgrades = [
  new game.upgrade({name:'5cl', run: function(){game.inv.chips.multiplier+=.05}, clicks:5, cost:10, desc:'increases click by .05'}),
  new game.upgrade({name:'25cl', run: function(){game.inv.chips.multiplier+=.25}, clicks:25, cost:50, desc:'increases click by .25'}),
  new game.upgrade({name:'50cl', run: function(){game.inv.chips.multiplier+=.50}, clicks:50, cost:100, desc:'increases click by .50'}),
	new game.upgrade({name:'100cl', run: function(){game.inv.chips.multiplier+=1}, clicks:100, cost:200, desc: 'increases click by 1'}),
	new game.upgrade({name:'200cl', run: function(){game.inv.chips.multiplier+=2}, clicks:200, cost:400, desc: 'increases click by 2'}),
	new game.upgrade({name:'400cl', run: function(){game.inv.chips.multiplier+=4}, clicks:400, cost:800, desc: 'increases click by 4'}),
	new game.upgrade({name:'800cl', run: function(){game.inv.chips.multiplier+=8}, clicks:800, cost:1600, desc: 'increases click by 8'}),
	new game.upgrade({name:'1600cl', run: function(){game.inv.chips.multiplier+=16}, clicks:1600, cost:3200, desc: 'increases click by 16'}),
	new game.upgrade({name:'2xPc', run: function(){game.inv.pc.multiplier+=1.2}, level:2, cost:100, desc: 'increases PC chip/s by 1.2'}),
	new game.upgrade({name:'2xMc', run: function(){game.inv.chips.multiplier+=1.2}, level:2, cost:200, desc:'increases click by 1.2'}),
	new game.upgrade({name:'3xPc', run: function(){game.inv.pc.multiplier+=1.5}, level:3, cost:1000, desc: 'increases PC chip/s by 1.5'}),
	new game.upgrade({name:'3xMc', run: function(){game.inv.chips.multiplier+=1.5}, level:3, cost:1500, desc:'increases click by 1.5'}),
];

game.item = function(vars) {
	this.quantity = vars.quantity||0;
	this.total = 0;
	this.lev = 0;
	this.base = vars.base||0;
	this.req  = vars.req ||1;
	this.cost = vars.cost||(this.base*game.stats.level);
	this.name = vars.name||"";
	this.update = function() { this.cost = Math.round(1000*Math.pow(2,game.stats.level-1)*(this.base + Math.pow(2,game.stats.level-1)*this.base*((this.lev/Math.pow(2,game.stats.level+this.req)))))/1000; }
	this.add = function() {if (game.inv.chips.quantity>=this.cost) {game.inv.chips.quantity= Math.round(1000*(game.inv.chips.quantity-this.cost))/1000; this.quantity++; this.total++; this.lev++;} else {console.log('fail');}};
	this.psec = 0;
	this.reset = function(mode) {
	  this.quantity = 0;
	  this.psec = 0;
	}
};

game.worker = function(vars){
  this.quantity = vars.quantity||0;
	this.total = 0;
	this.base = 10 * vars.base||0;
	this.cost = 10 * vars.cost||(this.base*game.stats.level);
	this.name = vars.name+" designer"||"";
	this.update = function() { this.cost = Math.round(1000*Math.pow(2,game.stats.level-1)*(this.base + this.quantity/Math.pow(2, game.stats.level)*this.base))/1000; }
	this.add = function() {if (game.inv.chips.quantity>=this.cost) {game.inv.chips.quantity= Math.round(1000*(game.inv.chips.quantity-this.cost))/1000; this.quantity++; this.total++; return(true)} else {console.log('fail');}};
	this.reset = function(mode) {
	  this.quantity = 0;
	}
};

game.inv = {};
game.inv.chips = {
	quantity : 0,
	total: 0,
	multiplier : 1,
	add : function(amt) {var a = game.stats.level*amt*((amt>=0)*this.multiplier); this.quantity+=a; this.total+=a;},
	reset : function(mode) {
	  this.quantity = 0;
    this.total = 0;
	  //mode can be 'hard' or 'soft'
	  this.multiplier = game.prestige.level;
	  if (mode=="hard") {this.multiplier = 1;}
	},
}
game.inv.items = [
	new game.item({name:"RAM", base:3, req: 2}),
	new game.item({name:"CPU", base:8,}),
	new game.item({name:"GPU", base:12}),
	new game.item({name:"Motherboard", base:10}),
	new game.item({name:"Case", base:6}),
	new game.item({name:"hard-drive", base:7}),
	new game.item({name:"disk-drive", base:5}),
];

game.inv.workers = [];

/* I could do workers on initialization... */

game.inv.pc = {
	quantity : 0,
	multiplier: 1,
	cps: 0,
	check: function() {
		for (var i = 0; i<game.inv.items.length; i++) { 
			if (game.inv.items[i].quantity < game.inv.items[i].req) { return false }
		} return true;
	},
	add: function() {
		if (this.check()) {
			for (var i = 0; i<game.inv.items.length; i++) {
			game.inv.items[i].quantity -= game.inv.items[i].req;
			}
			this.cps+= Math.pow(2,game.stats.level)/4;
			this.quantity+=1;
		} else {
			console.log('fail');
		}
	},
	reset: function(mode) {
	    this.quantity = 0;
	    this.multiplayer = game.prestige.level;
	    this.cps = 0;
	    if (mode=="hard") {
	      this.multiplier = 1;
	    }
	},
}

game.init = function(load) {
  //game.stats.stTime = var time = Math.round(new Date().getTime()*1000) / 1000
  $("#notifications").html("");
  $('#buttons').html("");
  $('#workers').html("");
  $('#upgrades').html("");
  $('#more').html("");
  game.inv.workers = [];
	$("#notifications").append(game.version);
	
	for (var i = 0; i<game.inv.items.length; i++) { 
	  game.inv.workers[i] = new game.worker(game.inv.items[i]);
	  console.log(JSON.stringify(game.inv.workers[i]));
		var a = JSON.stringify(game.inv.items[i]);
		$('#buttons').append("<span class=buy id="+game.inv.items[i].name+">"+game.inv.items[i].name+" - "+game.inv.items[i].cost+" - "+game.inv.items[i].quantity+" :: "+game.inv.items[i].req+"/PC</span>");
	};
	for (var i = 0; i<game.inv.workers.length; i++) {
	  $('#workers').append("<span class=asm id="+i+">"+game.inv.workers[i].name+" - "+game.inv.workers[i].cost+" - "+game.inv.workers[i].quantity+" :: "+game.inv.items[i].psec+"/s</span>");
	}
	for (var i = 0; i<game.upgrades.length; i++) { 
		var a = JSON.stringify(game.upgrades[i]);
		var hidden = '';
		if (game.upgrades[i].invisible==true) hidden = 'hidden';
		$('#upgrades').append("<span class='upgrade "+hidden+"' id="+game.upgrades[i].name+">"+game.upgrades[i].name+" - "+game.upgrades[i].cost+"</span>");
	};
	$('#more').append("<span id=chips>"+game.inv.chips.quantity+" chips</span>");
	$('#more').append("<span id=pcs>"+game.inv.pc.quantity+" PC's - "+game.inv.pc.cps+" chips/s</span>");
	
	$('#chips').click(function(e) { 
		game.inv.chips.add(1);
		game.stats.clicks+=1;
	});
	
	$('#lo').click(function(e) { 
		game.filesystem.load();
	});
	
	$('#sa').click(function(e) { 
		game.filesystem.save();
	});
	
	$('#hr').click(function(e) { 
		game.reset('hard');
	});
	
	$('#sr').click(function(e) { 
		game.reset('soft');
	});
	
	$('#pcs').click(function(e) {
		game.inv.pc.add(1); 
	});
	$(".buy").click(function(e) { 
		var i = $(".buy").index( this );
		game.inv.items[i].add(1);
	});
	$(".asm").click(function(e) { 
		var i = $(".asm").index( this );
		if(game.inv.workers[i].add()) {
		game.inv.items[i].psec+=game.inv.items[i].req*game.stats.level/100
		}
	});
	
	$(".upgrade").mouseenter(function(e) {
	    var i = $(".upgrade").index( this );
	    $("#stat").html(game.upgrades[i].desc);
	});
	$("span").mouseleave(function(e){
	  $("#stat").html("hello, this is a game about making computers because I can. That's it, figure it out on your own.");
	});
	
	
	$(".upgrade").click(function(e) { 
		var i = $(".upgrade").index( this );
		game.upgrades[i].use();
	});
	if(load!=false) {game.filesystem.load();}
	game.main();
}

game.notify = function(msg) {
  $("#notifications").html("");
  $("#notifications").append(game.version);
  $("#notifications").append(msg);
}

game.update = function(time) {
	$('#chips')[0].innerHTML = game.inv.chips.quantity.toFixed(3)+" chips";
	$('#pcs')[0].innerHTML = game.inv.pc.quantity.toFixed(2)+" PC's - "+(game.inv.pc.cps * game.inv.pc.multiplier).toFixed(3)+"chips/s";
	if (game.inv.pc.quantity>=Math.pow(2,game.stats.level+1)) {
		game.stats.level++;
		$('#buttons span').each(function(e) { game.inv.items[e].lev=0; game.inv.items[e].update(); });
		$('#workerss span').each(function(e) { game.inv.workers[e].update(); });
		game.notify('You have just reached level '+game.stats.level+'! - good job');
	}
	
	for (var i = 0; i<game.upgrades.length; i++) { 
			if (game.upgrades[i].invisible) {
				$('#upgrades span')[i].classList.add('hidden');
			} else {
				$('#upgrades span')[i].classList.remove('hidden');
			}
			
			if (game.inv.chips.quantity<game.upgrades[i].cost) { 
			  $('#upgrades span')[i].classList.add('disabled') 
	    } else { 
		    $('#upgrades span')[i].classList.remove('disabled') 
	    }
	    
			game.upgrades[i].update();
		};
	
	if (!game.inv.pc.check()) { 
		$('#pcs')[0].classList.add('disabled') 
	} else { 
		$('#pcs')[0].classList.remove('disabled') 
	}
	
	$('#buttons span').each(function(e) {
		game.inv.items[e].update();
		game.inv.items[e].quantity += game.inv.items[e].psec*(time-game.fps.lastTime);
		//game.inv.items[e].quantity = Math.round(1000*game.inv.items[e].quantity)/1000
		if (game.inv.items[e].cost>game.inv.chips.quantity) { 
			$('#buttons span')[e].classList.add('disabled') 
		} else { 
			$('#buttons span')[e].classList.remove('disabled') 
		}
		
		$('#buttons span')[e].innerHTML = game.inv.items[e].name+" - "+game.inv.items[e].cost.toFixed(3)+" - "+game.inv.items[e].quantity.toFixed(3)+" :: "+game.inv.items[e].req+"/PC"; 
	});
	
		$('#buttons span').each(function(e) {
		game.inv.workers[e].update();
		if (game.inv.workers[e].cost>game.inv.chips.quantity) { 
			$('#workers span')[e].classList.add('disabled') 
		} else { 
			$('#workers span')[e].classList.remove('disabled') 
		}
		
		$('#workers span')[e].innerHTML = game.inv.workers[e].name+" - "+game.inv.workers[e].cost+" - "+game.inv.workers[e].quantity+" :: "+game.inv.items[e].psec.toFixed(3)+"/s"; 
	});
	
	$('#upgrades span').each(function(e) {$('#upgrades span')[e].innerHTML = game.upgrades[e].name+" - "+game.upgrades[e].cost });
}

game.reset = function(mode) {
  //mode can be either hard or soft
  for (var i = 0; i<game.inv.items.length; i++) { 
		game.inv.items[i].reset(mode);
	};
	for (var i = 0; i<game.upgrades.length; i++) { 
		game.upgrades[i].reset(mode);
	};
	game.inv.chips.reset(mode);
	game.inv.pc.reset(mode);
	game.stats.level = 1;
	game.stats.clicks= 0;
	if (mode=='hard') { game.prestige.level = 1; }
	game.init(false);
}

game.main = function() {
	var time = Math.round(new Date().getTime()*10000) / 10000000;
	var dTime = Date.now() + 1000/game.tFPS;
	game.update(time);
	game.inv.chips.quantity+=(game.inv.pc.cps * game.inv.pc.multiplier)* (time-game.fps.lastTime);
	game.inv.chips.quantity = Math.round(game.inv.chips.quantity*1000)/1000;
	if (time >= game.fps.updateTime+1) {
		game.fps.set();
		console.log(game.fps.fps/(time-game.fps.updateTime)); 
		game.fps.frames=0;
		game.fps.updateTime = time;
	} else { game.fps.frames++;}
	game.fps.lastTime = time;
	setTimeout(game.main, Date.now()-dTime);
};
</script>
<style>
body, document { padding: 0px; margin: 0px; }
::selection { background: transparent; }
::-moz-selection { background: transparent; }
* { user-select: none; -moz-user-select: none;}
/*div > * not(.tooltip), div > * not(.) { display: block; position:relative; padding: 0px, 10px; margin:0px;}*/
span.upgrade{display: inline-block; background: #22dd66;}
span.upgrade:hover{background: #44ff88;}
div #upgrades span.hidden{ display: none !important; }
span {display: inline-block; outline: black 1px solid; background: #2266dd; transition: background 0.2s; padding: 10px 3px; margin: 2px 2px;}
span:hover {cursor:grab; background: #4488ff; color: #;}
#page {width: 100vw; height: 100vh; background: #999; padding: 0px; margin: 0px;}
.disabled, span .disabled { background: #666 !important; color:#111 !important }
.disabled:hover, span .disabled:hover  {background: #777 !important; color:#222 !important; }
ul span { padding: 5px 3px; }
div ul span {border:none;}
div{position: relative;  margin: 0px; padding: 0px; display: block;}
#stat {right:0px;bottom:0px; text-align: center; width:300px; height: 75px; background: rgba(0,127,255,0.3); border: rgba(0,127,255,0.7); }
div div#header {
  width: 100vw;
  background: rgba(60,60,60,0.2);
  height: 50px;
  transition: background 0.2s;
  padding: 0px; margin:0px;
}
div div#header:hover, div.head > *:hover {
  background: rgba(60,60,60,0.5);
}

</style>
</head>
<body onload="game.init();">
  <div id='page' style="padding:0px">
    <div id="header">
      <span id="notifications">-- notifications -- </span>
      <ul id="menu" style="position: absolute; display: block; top:0px; right:0px;">
        <span id='sa' style="display: inline; width: 100px;">Save</span>
        <span id='lo' style="display: inline; width: 100px;">Load</span>
        <span id='hr' style="display: inline; width: 100px;">Reset [hard]</span>
        <span id='sr' style="display: inline; width: 100px;">Reset [soft]</span>
      </ul>
    </div>
    <div style="width: 50vw; display: block;">
      <div id="buttons"  style="display: inline-block"> </div>
      <div id="workers"  style="display: inline-block"> </div>
      <div id="more" style="display: inline-block;"> </div>
    </div>
    <div id="upgrades" style="position: absolute; display: inline-block; padding: 0; margin: 0; right:0px; top:50px; width: 50vw; height: calc(100vh - 50px); background: rgba(0,0,0,0.1);"></div>
    <div id="stat" style="position: fixed">hello, this is a game about making computers because I can. That's it, figure it out on your own.</div>
  </div>
</body>
</html>